Contest2071 - 湖南多校对抗赛(2015.03.28)

Contest2071 - 湖南多校对抗赛(2015.03.28) 

 本次比赛试题由湖南大学ACM校队原创

 

 http://acm.csu.edu.cn/OnlineJudge/contest.php?cid=2071

Problem A: Rectangle

Time Limit: 1 Sec  Memory Limit: 256 MB
Submit: 210  Solved: 48
[Submit][Status][Web Board]

Description

Now ,there are some rectangles. The area of these rectangles is 1* x or 2 * x ,and now you need find a big enough rectangle( 2 * m) so that you can put all rectangles into it(these rectangles can't rotate). please calculate the minimum m satisfy the condition.

 

Input

There are some tests ,the first line give you the test number. 
Each test will give you a number n (1<=n<=100)show the rectangles number .The following n rows , each row will give you tow number a and b. (a = 1 or 2 , 1<=b<=100).

 

Output

Each test you will output the minimum number m to fill all these rectangles.

 

Sample Input

2
3
1 2
2 2
2 3
3
1 2
1 2
1 3

Sample Output

7
4



题意:就是说有1*x或者2*x的长方形,你有2*m的总空间,问你m的最小值;
思路:如果是2*x那么x必定是要加的,但是1*x则可以叠加,so把所有的1的宽x加起来,用0-1背包一下就行了;
转载请注明出处:
寻找&星空の孩子
#include<stdio.h>
const int N = 10005;
int main()
{
    int dp[N],ans,t,a[N],b[N],n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        ans=0;
        for(int i=0;i<=N;i++)
            dp[i]=0;
        int V=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&a[i],&b[i]);
            if(a[i]==1)
                V+=b[i];
        }
        for(int i=1;i<=n;i++)
        if(a[i]==2)
          ans+=b[i];
        else
        {
            for(int v=V/2;v>=b[i];v--)
                if(dp[v]<dp[v-b[i]]+b[i])
                dp[v]=dp[v-b[i]]+b[i];
        }
        int aa=V-dp[V/2];
        if(aa<dp[V/2])
            aa=dp[V/2];
        ans+=aa;
        printf("%d\n",ans);
    }
    return 0;
}

/*
2
3
1 2
2 2
2 3
3
1 2
1 2
1 3
*/

 

 

Problem B: Design road

Time Limit: 2 Sec  Memory Limit: 256 MB
Submit: 43  Solved: 18
[Submit][Status][Web Board]

Description

You need to design road from (0, 0) to (x, y) in plane with the lowest cost. Unfortunately, there are N Rivers between (0, 0) and (x, y).It costs c1 Yuan RMB per meter to build road, and it costs c2 Yuan RMB per meter to build a bridge. All rivers are parallel to the Y axis with infinite length.

 

Input

There are several test cases.
Each test case contains 5 positive integers N,x,y,c1,c2 in the first line.(N ≤ 1000,1 ≤ x,y≤ 100,000,1 ≤ c1,c2 ≤ 1000).
The following N lines, each line contains 2 positive integer xi, wi ( 1 ≤ i ≤ N ,1 ≤ xi ≤x, xi-1+wi-1 < xi , xN+wN ≤ x),indicate the i-th river(left bank) locate xi with wi width.
The input will finish with the end of file.

 

Output

For each the case, your program will output the least cost P on separate line, the P will be to two decimal places .

 

Sample Input

1 300 400 100 100
100 50
1 150 90 250 520
30 120

Sample Output

50000.00
80100.00

 题意:修路:从(0,0)~(x,y),n个数表示有第二行开始有n行表示有n条河,xi是河的起始位置,wi是河的宽度,有水的地方要修桥,而x,y表示修路的端点,C1表示修路每米的花费,C2表示修桥每米的花费,问你最后花费的最少金额!

思路:先把有河的地方都和到一起,然后它的宽度就知道了,那么就把高度三分,找花费最小的点;看代码就知道了!哈哈

转载请注明出处:寻找&星空の孩子

 

 

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;

int n;
double x,y,c1,c2,sum,ans;

double dis(double x1,double y1,double x2,double y2)
{
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

void fen_3(double l,double r)
{
    double mid1 = l+(r-l)/3;
    double mid2 = l+(r-l)*2/3;
    double s1 = dis(0,0,sum,mid1)*c2+dis(sum,mid1,x,y)*c1;
    double s2 = dis(0,0,sum,mid2)*c2+dis(sum,mid2,x,y)*c1;
    if(fabs(s1-s2)<1e-6)
    {
        ans = s2;
        return;
    }
    if(s1>s2)
    fen_3(mid1,r);
    else
    fen_3(l,mid2);
}

int main()
{
    int i,j,k;
    while(~scanf("%d%lf%lf%lf%lf",&n,&x,&y,&c1,&c2))
    {
        sum = 0;
        for(i = 0;i<n;i++)
        {
            double tx,ty;
            scanf("%lf%lf",&tx,&ty);
            sum+=ty;
        }
        fen_3(0,y);
        printf("%.2f\n",ans);
    }

    return 0;
}




/**************************************************************
    Problem: 1548
    User: aking2015
    Language: C++
    Result: Accepted
    Time:84 ms
    Memory:976 kb
****************************************************************/

 

 

Problem C: Navigition Problem

Time Limit: 1 Sec  Memory Limit: 256 MB
Submit: 56  Solved: 8
[Submit][Status][Web Board]

Description

Navigation is a field of study that focuses on the process of monitoring and controlling the movement of a craft or vehicle from one place to another. The field of navigation includes four general categories: land navigation, marine navigation, aeronautic navigation, and space navigation. (From Wikipedia)
Recently, slowalker encountered a problem in the project development of Navigition APP. In order to provide users with accurate navigation service , the Navigation APP should re-initiate geographic location after the user walked DIST meters. Well, here comes the problem. Given the Road Information which could be abstracted as N segments in two-dimensional space and the distance DIST, your task is to calculate all the postion where the Navigition APP should re-initiate geographic location.

 

Input

The input file contains multiple test cases.
For each test case,the first line contains an interger N and a real number DIST. The following N+1 lines describe the road information.
You should proceed to the end of file.

Hint:
1 <= N <= 1000
0 < DIST < 10,000

 

Output

For each the case, your program will output all the positions where the Navigition APP should re-initiate geographic location. Output “No Such Points.” if there is no such postion.

 

Sample Input

2 0.50
0.00 0.00
1.00 0.00
1.00 1.00

Sample Output

0.50,0.00
1.00,0.00
1.00,0.50
1.00,1.00

HINT

 暂没做出。。。。。

 

Problem D: Simple String

Time Limit: 1 Sec  Memory Limit: 256 MB
Submit: 74  Solved: 35
[Submit][Status][Web Board]

Description

Welcome,this is the 2015 3th Multiple Universities Programming Contest ,Changsha ,Hunan Province. In order to let you feel fun, ACgege will give you a simple problem. But is that true? OK, let’s enjoy it.
There are three strings A , B and C. The length of the string A is 2*N, and the length of the string B and C is same to A. You can take N characters from A and take N characters from B. Can you set them to C ?

 

Input

There are several test cases.
Each test case contains three lines A,B,C. They only contain upper case letter.
0<N<100000
The input will finish with the end of file.

 

Output

For each the case, if you can get C, please print “YES”. If you cann’t get C, please print “NO”.

 

Sample Input

AABB
BBCC
AACC
AAAA
BBBB
AAAA

Sample Output

YES
NO

 题意:有A,B,C三个集合,取A、B串的各一半,问能不能组成C;

思路:记录每个字符出现的个数,大于一半长度取一半;然后a[i]+b[i]<c[i]的就输出NO;

然后定b[i]判断min_a[i]+=c[i]-b[i];max_a[i]+=a[i];最后判断a[i]的长度len/2是否在min和max之间,在之间就输出YES。不

在之间就输出NO;

转载请注明出处:寻找&星空の孩子

#include<stdio.h>
#include<string.h>
const int N = 200005;
 
char A[N],B[N],C[N];
 
int main()
{
    int a[30],b[30],c[30];
    int mint,maxt,flag,len;
    while(scanf("%s%s%s",A,B,C)>0)
    {
        len=strlen(A);
        for(int i=0;i<=26;i++)
        a[i]=b[i]=c[i]=0;
 
        for(int i=0;i<len;i++)
        {
            int j;
            j=A[i]-'A'; a[j]++;
            j=B[i]-'A'; b[j]++;
            j=C[i]-'A'; c[j]++;
        }
        flag=0;
        for(int i=0;i<26;i++)
        {
            if(a[i]>len/2)
                a[i]=len/2;
            if(b[i]>len/2)
                b[i]=len/2;
            if(a[i]+b[i]<c[i])
            {
                flag=1; break;
            }
        }
        if(flag)
        {
            printf("NO\n");continue;
        }
        mint=maxt=0;
        for(int i=0;i<26;i++)
        {
            if(c[i]>b[i])
                mint+=c[i]-b[i];
            if(a[i]>=c[i])
                maxt+=c[i];
            else
                maxt+=a[i];
        }
 //       printf("%d   %d\n",mint,maxt);
        if(len/2>=mint&&len/2<=maxt)
            printf("YES\n");
        else
            printf("NO\n");
    }
}
 
/**************************************************************
    Problem: 1550
    User: aking2015
    Language: C++
    Result: Accepted
    Time:24 ms
    Memory:1548 kb
****************************************************************/

 

 

 

 

Problem E: Longest Increasing Subsequence Again

Time Limit: 2 Sec  Memory Limit: 256 MB
Submit: 27  Solved: 13
[Submit][Status][Web Board]

Description

Give you a numeric sequence. If you can demolish arbitrary amount of numbers, what is the length of the longest increasing sequence, which is made up of consecutive numbers? It sounds like Longest Increasing Subsequence at first sight. So, there is another limitation: the numbers you deleted must be consecutive.

 

Input

There are several test cases.
For each test case, the first line of input contains the length of sequence N(1≤N≤10^4). The second line contains the elements of sequence——N positive integers not larger than 10^4.

 

Output

For each the case, output one integer per line, denoting the length of the longest increasing sequence of consecutive numbers, which is achievable by demolishing some(may be zero) consecutive numbers. 

 

Sample Input

7
1 7 3 5 9 4 8
6
2 3 100 4 4 5

Sample Output

4
4

HINT

 

ome to CSU Online Judge!
 
 
题意:最长公共子序列,要求删去连续的n个数,求余下的连续的最长子序列长度;
思路:先分段,然后用线段树更新。。。。。详见代码;
转载请注明出处:寻找&星空の孩子
#include<stdio.h>
#include<algorithm>
using namespace std;
const int N = 10005;
struct qj
{
    int l,r;
}kuai[N];
int b[N],tn,n,a[N],k[N],tree[N*4];
void builde(int l,int r,int e)
{
    int m=(l+r)/2;
    tree[e]=0;
    if(l==r)
        return ;
    builde(l,m,e*2);
    builde(m+1,r,e*2+1);
}
void settree(int l,int r,int e,int id,int ans)
{
    int m=(l+r)/2;
    if(tree[e]<ans)
        tree[e]=ans;
    if(l==r)
    {
         return ;
    }
    if(id<=m)
        settree(l,m,e*2,id,ans);
    else
        settree(m+1,r,e*2+1,id,ans);
}
int findans(int l,int r,int e,int id)
{
    int m=(l+r)/2,ans=0;
    if(l==r)
        return 0;
    if(id<=m)
    {
        ans=findans(l,m,e*2,id);
        if(ans<tree[e*2+1])
            ans=tree[e*2+1];
        return ans;
    }
    else
        return findans(m+1,r,e*2+1,id);
}
int cmp(int aa,int bb)
{
    return aa<bb;
}
void cut()
{
    tn=1;
    sort(b+1,b+1+n,cmp);
    for(int i=2;i<=n;i++)
        if(b[i]!=b[tn])
            b[++tn]=b[i];
}
int two(int aa)
{
    int l,r,m;
    l=1;r=tn;
    while(l<=r)
    {
        m=(l+r)/2;
        if(b[m]==aa)
            return m;
        if(b[m]>aa)
            r=m-1;
        else l=m+1;
    }
    return m;
}
int main()
{
    while(scanf("%d",&n)>0)
    {
        if(n==0)
        {
            printf("0\n");continue;
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            b[i]=a[i];
        }
        cut();
        builde(1,tn,1);

        int m=1;
        kuai[m].l=kuai[m].r=1;
        for(int i=2;i<=n;i++)
         if(a[kuai[m].r]>=a[i])
        {
            m++; kuai[m].l=kuai[m].r=i;
        }
        else
            kuai[m].r++;

        for(int i=1;i<=m;i++)
        {
            for(int j=kuai[i].r;j>=kuai[i].l;j--)
                k[j]=kuai[i].r-j+1;
        }
        int ans=0;
        for(int i=m;i>0;i--)
        {
            int aaa,id;
            for(int j=kuai[i].r;j>=kuai[i].l;j--)
            {
                id=two(a[j]);
                aaa=j-kuai[i].l+1;
                aaa+=findans(1,tn,1,id);
                if(ans<aaa)
                ans=aaa;
            }

            for(int j=kuai[i].r;j>=kuai[i].l;j--)
            {
                id=two(a[j]);
                settree(1,tn,1,id,k[j]);
            }
        }
        printf("%d\n",ans);
    }
}

/**************************************************************
    Problem: 1551
    User: aking2015
    Language: C++
    Result: Accepted
    Time:192 ms
    Memory:1320 kb
****************************************************************/

 

Problem F: Friends

Time Limit: 3 Sec  Memory Limit: 256 MB
Submit: 131  Solved: 25
[Submit][Status][Web Board]

Description

On an alien planet, every extraterrestrial is born with a number. If the sum of two numbers is a prime number, then two extraterrestrials can be friends. But every extraterrestrial can only has at most one friend. You are given all number of the extraterrestrials, please determining the maximum number of friend pair.

 

Input

There are several test cases.
Each test start with positive integers N(1 ≤ N ≤ 100), which means there are N extraterrestrials on the alien planet. 
The following N lines, each line contains a positive integer pi ( 2 ≤ pi ≤10^18),indicate the i-th extraterrestrial is born with pi number.
The input will finish with the end of file.

 

Output

For each the case, your program will output maximum number of friend pair.

 

Sample Input

3
2
2
3

4
2
5
3
8

Sample Output

1
2

HINT

 

 二分匹配

#include<stdio.h>
#include<math.h>
#include <algorithm>
#include<string.h>
#include <time.h>
using namespace std;
#define ll long long
//-----大素数的判断-------
ll mult_mod(ll a,ll b,ll n)
{
    ll s=0;
    while(b)
    {
        if(b&1) s=(s+a)%n;
        a=(a+a)%n;
        b>>=1;
    }
    return s;
}
 
ll pow_mod(ll a,ll b,ll n)
{
    ll s=1;
    while(b)
    {
        if(b&1) s=mult_mod(s,a,n);
        a=mult_mod(a,a,n);
        b>>=1;
    }
    return s;
}
 
int Prime(ll n)
{
    ll u=n-1,pre,x;
    int i,j,k=0;
    if(n==2||n==3||n==5||n==7||n==11)  return 1;
    if(n==1||(!(n%2))||(!(n%3))||(!(n%5))||(!(n%7))||(!(n%11)))   return 0;
    for(;!(u&1);k++,u>>=1);
    srand((ll)time(0));
    for(i=0;i<5;i++)
    {
        x=rand()%(n-2)+2;
        x=pow_mod(x,u,n);
        pre=x;
        for(j=0;j<k;j++)
        {
            x=mult_mod(x,x,n);
            if(x==1&&pre!=1&&pre!=(n-1))
                return 0;
            pre=x;
        }
        if(x!=1)  return 0;
    }
    return 1;
}
int n,ok[105][105],mark[105],vist[105];
int DFS(int x)
{
    for(int i=1;i<=n;i++)
    if(ok[x][i]&&vist[i]==0)
    {
        vist[i]=1;
        if(mark[i]==0||DFS(mark[i]))
        {
            mark[i]=x; return 1;
        }
    }
    return 0;
}
int main()
{
 
    ll a[105];
    while(scanf("%d",&n)>0)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
        }
        memset(ok,0,sizeof(ok));
        for(int i=1;i<n;i++)
        for(int j=i+1;j<=n;j++)
        if(Prime(a[i]+a[j]))
            ok[i][j]=ok[j][i]=1;
 
        int ans=0;
        memset(mark,0,sizeof(mark));
        for(int i=1;i<=n;i++)
        {
            memset(vist,0,sizeof(vist));
            ans+=DFS(i);
        }
 
        printf("%d\n",ans/2);
    }
}
 
/**************************************************************
    Problem: 1552
    User: aking2015
    Language: C++
    Result: Accepted
    Time:1640 ms
    Memory:1012 kb
****************************************************************/

 

Problem G: Good subsequence

Time Limit: 2 Sec  Memory Limit: 256 MB
Submit: 208  Solved: 48
[Submit][Status][Web Board]

Description

Give you a sequence of n numbers, and a number k you should find the max length of Good subsequence. Good subsequence is a continuous subsequence of the given sequence and its maximum value - minimum value<=k. For example n=5, k=2, the sequence ={5, 4, 2, 3, 1}. The answer is 3, the good subsequence are {4, 2, 3} or {2, 3, 1}.

 

Input

There are several test cases.
Each test case contains two line. the first line are two numbers indicates n and k (1<=n<=10,000, 1<=k<=1,000,000,000). The second line give the sequence of n numbers a[i] (1<=i<=n, 1<=a[i]<=1,000,000,000). 
The input will finish with the end of file.

 

Output

For each the case, output one integer indicates the answer.

 

Sample Input

5 2
5 4 2 3 1
1 1
1

Sample Output

3
1

HINT

 题意:最长连续子序列,要求子序列中最大减去最小的数小于k

思路:。。。。。。

转载请注明出处:寻找&星空の孩子
#include <stdio.h>
#include <stdio.h>
#include <algorithm>
#include <set>
using namespace std;

set<int> st;
int a[10005];

int main()
{
    int n,k,i,j,ans;
    while(~scanf("%d%d",&n,&k))
    {
        st.clear();
        for(i = 1;i<=n;i++)
        scanf("%d",&a[i]);
        ans = 0;
        for(i = 1,j = 1;i<=n;i++)
        {
            st.insert(a[i]);
            while(*st.rbegin()-*st.begin()>k)
            {
                st.erase(st.find(a[j]));
                j++;
            }
            ans = max(ans,i-j+1);
        }
        printf("%d\n",ans);
    }

    return 0;
}

/**************************************************************
    Problem: 1553
    User: aking2015
    Language: C++
    Result: Accepted
    Time:652 ms
    Memory:1104 kb
****************************************************************/

 

 

 

Problem H: SG Value

Time Limit: 5 Sec  Memory Limit: 256 MB
Submit: 55  Solved: 4
[Submit][Status][Web Board]

Description

The SG value of a set (multiset) is the minimum positive integer that could not be constituted of the number in this set.
You will be start with an empty set, now there are two opertions:
1. insert a number x into the set;
2. query the SG value of current set.

 

Input

Input contains multiple test cases. Each test case starts with a number N (0 < N <= 1e5) -- the total number of opertions.
The next N lines contain one opertion each.
1 x means insert a namber x into the set;
2 means query the SG value of current set.

 

Output

For each query output the SG value of current set.

 

Sample Input

5
2
1 1
2
1 1
2

Sample Output

1
2
3




Problem I: Inversion Sequence

Time Limit: 2 Sec  Memory Limit: 256 MB
Submit: 90  Solved: 26
[Submit][Status][Web Board]

Description

For sequence i1, i2, i3, … , iN, we set aj to be the number of members in the sequence which are prior to j and greater to j at the same time. The sequence a1, a2, a3, … , aN is referred to as the inversion sequence of the original sequence (i1, i2, i3, … , iN). For example, sequence 1, 2, 0, 1, 0 is the inversion sequence of sequence 3, 1, 5, 2, 4. Your task is to find a full permutation of 1~N that is an original sequence of a given inversion sequence. If there is no permutation meets the conditions please output “No solution”.

 

Input

There are several test cases.
Each test case contains 1 positive integers N in the first line.(1 ≤ N ≤ 10000).
Followed in the next line is an inversion sequence a1, a2, a3, … , aN (0 ≤ aj < N)
The input will finish with the end of file.

 

Output

For each case, please output the permutation of 1~N in one line. If there is no permutation meets the conditions, please output “No solution”.

 

Sample Input

5
1 2 0 1 0
3
0 0 0
2
1 1

Sample Output

3 1 5 2 4
1 2 3
No solution

HINT

 

转载请注明出处:寻找&星空の孩子
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
#define ls 2*i
#define rs 2*i+1
const int L = 10005;
struct node
{
    int l,r,n;
} a[L*4];
int n,ans[L],pos;

void push_up(int i)
{
    a[i].n = a[ls].n+a[rs].n;
}

void init(int l,int r,int i)
{
    a[i].l = l;
    a[i].r = r;
    if(l==r)
    {
        a[i].n = 1;
        return ;
    }
    int mid = (l+r)/2;
    init(l,mid,ls);
    init(mid+1,r,rs);
    push_up(i);
}

void query(int i,int x)
{
    if(a[i].l == a[i].r)
    {
        pos = a[i].l;
        a[i].n = 0;
        return ;
    }
    if(x<=a[ls].n)
        query(ls,x);
    else
        query(rs,x-a[ls].n);
    push_up(i);
}

int main()
{
    int i,j,k,x;
    while(~scanf("%d",&n))
    {
        memset(ans,0,sizeof(ans));
        init(1,n,1);
        int flag = 0;
        for(i = 1; i<=n; i++)
        {
            scanf("%d",&x);
            if(flag)
                continue;
            if(a[1].n<x+1)
            {
                flag = 1;
                continue;
            }
            else
            {
                query(1,x+1);
                ans[pos] = i;
            }
        }
        if(flag)
            printf("No solution\n");
        else
        {
            printf("%d",ans[1]);
            for(i = 2; i<=n; i++)
                printf(" %d",ans[i]);
            printf("\n");
        }
    }

    return 0;
}

/**************************************************************
    Problem: 1555
    User: aking2015
    Language: C++
    Result: Accepted
    Time:192 ms
    Memory:1472 kb
****************************************************************/

 

 

 

 

 

 

Problem J: Jerry's trouble

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 96  Solved: 46
[Submit][Status][Web Board]

Description

 Jerry is caught by Tom. He was penned up in one room with a door, which only can be opened by its code. The code is the answer of the sum of the sequence of number written on the door. The type of the sequence of number is

 

But Jerry’s mathematics is poor, help him to escape from the room.

Input

 There are some cases (about 500). For each case, there are two integer numbers n, m describe as above ( 1 <= n < 1 000 000, 1 <= m < 1000).

Output

 For each case, you program will output the answer of the sum of the sequence of number (mod 1e9+7).

Sample Input

4 1
5 1
4 2
5 2
4 3

Sample Output

10
15
30
55
100

HINT

转载请注明出处:寻找&星空の孩子
#include<stdio.h>
#define LL long long
const LL mod=1e9+7;
inline LL two(LL &a,LL m)
{
    if(m==0)
        return 1;
    LL ans=two(a,m/2);
    ans=(ans*ans)%mod;
    if(m&1)
        ans=(ans*a)%mod;
    return ans;
}
int main()
{
    LL n,m,i;
    while(scanf("%lld%lld",&n,&m)>0)
    {
       LL ans=0;
        for(i=1;i<=n;i++)
            ans=(ans+two(i,m))%mod;
        printf("%lld\n",ans);
    }
}

/**************************************************************
    Problem: 1556
    User: aking2015
    Language: C++
    Result: Accepted
    Time:3012 ms
    Memory:964 kb
****************************************************************/

 

 

 

 

 

 

posted @ 2015-03-28 23:10  寻找&星空の孩子  阅读(803)  评论(4编辑  收藏  举报