• 2015福建省赛


     Problem A Super Mobile Charger

    Accept: 217    Submit: 402 Time Limit: 1000 mSec    Memory Limit : 32768 KB

     Problem Description

    While HIT ACM Group finished their contest in Shanghai and is heading back Harbin, their train was delayed due to the heavy snow. Their mobile phones are all running out of battery very quick. Luckily, zb has a super mobile charger that can charge all phones.

    There are N people on the train, and the i-th phone has p[i] percentage of power, the super mobile charger can charge at most M percentage of power.

    Now zb wants to know, at most how many phones can be charged to full power. (100 percent means full power.)

     Input

    The first line contains an integer T, meaning the number of the cases (1 <= T <= 50.).

    For each test case, the first line contains two integers N, M(1 <= N <= 100,0 <= M <= 10000) , the second line contains N integers p[i](0 <= p[i] <= 100) meaning the percentage of power of the i-th phone.

     Output

    For each test case, output the answer of the question.

     Sample Input

    2 3 10 100 99 90 3 1000 0 0 0

     Sample Output

    2 3

    题解:水题,就是说,火车晚点了,就有一块充电宝,能冲一定电量,问能把多少个人的手机充满电;

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    using namespace std;
    const int INF=0x3f3f3f3f;
    #define mem(x,y) memset(x,y,sizeof(x))
    #define SI(x) scanf("%d",&x)
    #define PI(x) printf("%d",x)
    #define T_T while(T--)
    const int MAXN=110;
    int a[MAXN];
    int main(){
    	int T,N,M;
    	SI(T);
    	T_T{
    		SI(N);SI(M);
    		for(int i=0;i<N;i++)SI(a[i]),a[i]=100-a[i];
    		sort(a,a+N);
    		int ans=0;
    		for(int i=0;i<N;i++){
    			M-=a[i];
    			if(M<0)break;
    			ans++;
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

      

     Problem B Common Tangents

    Accept: 191    Submit: 608 Time Limit: 1000 mSec    Memory Limit : 32768 KB

     Problem Description

    Two different circles can have at most four common tangents.

    The picture below is an illustration of two circles with four common tangents.

    Now given the center and radius of two circles, your job is to find how many common tangents between them.

     Input

    The first line contains an integer T, meaning the number of the cases (1 <= T <= 50.).

    For each test case, there is one line contains six integers x1 (−100 ≤ x1 ≤ 100), y1 (−100 ≤ y1 ≤ 100), r1 (0 < r1 ≤ 200), x2 (−100 ≤ x2 ≤ 100), y2 (−100 ≤ y2 ≤ 100), r2 (0 < r2 ≤ 200). Here (x1, y1) and (x2, y2) are the coordinates of the center of the first circle and second circle respectively, r1 is the radius of the first circle and r2 is the radius of the second circle.

     Output

    For each test case, output the corresponding answer in one line.

    If there is infinite number of tangents between the two circles then output -1.

     Sample Input

    3 10 10 5 20 20 5 10 10 10 20 20 10 10 10 5 20 10 5

     Sample Output

    4 2 3

     题解:相切于两个圆的直线条数;考虑全情况即可;

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    using namespace std;
    const int INF=0x3f3f3f3f;
    #define mem(x,y) memset(x,y,sizeof(x))
    #define SI(x) scanf("%d",&x)
    #define PI(x) printf("%d",x)
    #define T_T while(T--)
    double js(int x,int y,int x1,int y1){
    	int xx=x-x1,yy=y-y1;
    	return sqrt(xx*xx+yy*yy);
    }
    int main(){
    	int T,x1,x2,y1,y2,r1,r2;
    	SI(T);
    	T_T{
    		scanf("%d%d%d%d%d%d",&x1,&y1,&r1,&x2,&y2,&r2);
    		double d=js(x1,y1,x2,y2);
    		if(d==0&&r1==r2){
    			puts("-1");continue;
    		}
    		if(d<abs(r1-r2)){
    			puts("0");continue;
    		}
    		if(d==abs(r1-r2)){
    			puts("1");continue;
    		}
    		if(r1+r2>d){
    			puts("2");continue;
    		}
    		if(d==r1+r2){
    			puts("3");continue;
    		}
    		if(r1+r2<d){
    			puts("4");continue;
    		}
    	}
    	return 0;
    }
    

      

     Problem C Knapsack problem

    Accept: 83    Submit: 457 Time Limit: 3000 mSec    Memory Limit : 32768 KB

     Problem Description

    Given a set of n items, each with a weight w[i] and a value v[i], determine a way to choose the items into a knapsack so that the total weight is less than or equal to a given limit B and the total value is as large as possible. Find the maximum total value. (Note that each item can be only chosen once).

     Input

    The first line contains the integer T indicating to the number of test cases.

    For each test case, the first line contains the integers n and B.

    Following n lines provide the information of each item.

    The i-th line contains the weight w[i] and the value v[i] of the i-th item respectively.

    1 <= number of test cases <= 100

    1 <= n <= 500

    1 <= B, w[i] <= 1000000000

    1 <= v[1]+v[2]+...+v[n] <= 5000

    All the inputs are integers.

     Output

    For each test case, output the maximum value.

     Sample Input

    1 5 15 12 4 2 2 1 1 4 10 1 2

     Sample Output

    15

     题解:给你一个背包,问背包中放的价值最大的值,由于质量太大,把背包当成价值,也就是相同价值放的最小质量;

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    using namespace std;
    const int INF=0x3f3f3f3f;
    #define mem(x,y) memset(x,y,sizeof(x))
    #define SI(x) scanf("%d",&x)
    #define PI(x) printf("%d",x)
    #define T_T while(T--)
    typedef long long LL;
    const int MAXN=5050;
    LL bag[MAXN];
    struct Node{
    	int w,v;
    };
    Node dt[MAXN];
    int main(){
    	int T,n,m,V;
    	SI(T);
    	T_T{
    		SI(n);SI(m);
    		V=0;
    		for(int i=0;i<n;i++)SI(dt[i].w),SI(dt[i].v),V+=dt[i].v;
    		mem(bag,INF);
    		bag[0]=0;
    		for(int i=0;i<n;i++){
    			for(int j=V;j>=dt[i].v;j--){
    				bag[j]=min(bag[j],bag[j-dt[i].v]+dt[i].w);
    			}
    		}
    		for(int j=V;j>=0;j--){
    			if(bag[j]<=m){
    				printf("%d
    ",j);
    				break;
    			}
    		}
    	}
    	return 0;
    }
    

      

     Problem E The Longest Straight

    Accept: 71    Submit: 293 Time Limit: 1000 mSec    Memory Limit : 32768 KB

     Problem Description

    ZB is playing a card game where the goal is to make straights. Each card in the deck has a number between 1 and M(including 1 and M). A straight is a sequence of cards with consecutive values. Values do not wrap around, so 1 does not come after M. In addition to regular cards, the deck also contains jokers. Each joker can be used as any valid number (between 1 and M, including 1 and M).

    You will be given N integers card[1] .. card[n] referring to the cards in your hand. Jokers are represented by zeros, and other cards are represented by their values. ZB wants to know the number of cards in the longest straight that can be formed using one or more cards from his hand.

     Input

    The first line contains an integer T, meaning the number of the cases.

    For each test case:

    The first line there are two integers N and M in the first line (1 <= N, M <= 100000), and the second line contains N integers card[i] (0 <= card[i] <= M).

     Output

    For each test case, output a single integer in a line -- the longest straight ZB can get.

     Sample Input

    2 7 11 0 6 5 3 0 10 11 8 1000 100 100 100 101 100 99 97 103

     Sample Output

    5 3

     题解:

    让求最长连续上升的序列长度,可任意摆放次序;其中0可以代表1~M之间的任意一个数;

    离散化数组,把里面元素从0开始,出现过就是前一个值,没出现过就是前一个+1;计数0出现的次数n0;然后0~M对于每一个数进行二分查找,找出差值为n0的最大序列长度即可;

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    using namespace std;
    const int INF=0x3f3f3f3f;
    #define mem(x,y) memset(x,y,sizeof(x))
    #define SI(x) scanf("%d",&x)
    #define PI(x) printf("%d",x)
    #define T_T while(T--)
    const int MAXN=100010;
    int a[MAXN],b[MAXN];
    int erfen(int l,int r,int i,int x){
    	int mid;
    	while(l<=r){
    		mid=(l+r)>>1;
    		if(b[mid]-b[i]>x)r=mid-1;
    		else l=mid+1;
    	}
    	return l-i-1;
    }
    int main(){
    	int T,N,M,x;
    	SI(T);
    	T_T{
    		SI(N);SI(M);
    		mem(a,0);
    		int n0=0;
    		for(int i=0;i<N;i++){
    			SI(x);
    			if(x==0)n0++;
    			else a[x]=1;
    		}
    		b[0]=0;
    		for(int i=1;i<=M;i++){
    			if(a[i])
    				b[i]=b[i-1];
    			else b[i]=b[i-1]+1;
    		}
    		int ans=0;
    		for(int i=0;i<=M;i++){
    			ans=max(ans,erfen(i,M,i,n0));
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

      

    Problem J RunningMan

    Accept: 131    Submit: 577 Time Limit: 1000 mSec    Memory Limit : 32768 KB

     Problem Description

    ZB loves watching RunningMan! There's a game in RunningMan called 100 vs 100.

    There are two teams, each of many people. There are 3 rounds of fighting, in each round the two teams send some people to fight. In each round, whichever team sends more people wins, and if the two teams send the same amount of people, RunningMan team wins. Each person can be sent out to only one round. The team wins 2 rounds win the whole game. Note, the arrangement of the fighter in three rounds must be decided before the whole game starts.

    We know that there are N people on the RunningMan team, and that there are M people on the opposite team. Now zb wants to know whether there exists an arrangement of people for the RunningMan team so that they can always win, no matter how the opposite team arrange their people.

     Input

    The first line contains an integer T, meaning the number of the cases. 1 <= T <= 50.

    For each test case, there's one line consists of two integers N and M. (1 <= N, M <= 10^9).

     Output

    For each test case, Output "Yes" if there exists an arrangement of people so that the RunningMan team can always win. "No" if there isn't such an arrangement. (Without the quotation marks.)

     Sample Input

    2 100 100 200 100

     Sample Output

    No Yes

     题解:两个队进行比赛,跑男队人数是N,跑女队人数是M,每次两个队分别选出人数进行比赛,三局两胜,派出人多的队胜,人数相等跑男队胜;问是否无论女队怎么派人,跑男必胜;

    很容易想,把这个数分成三波,跑男队要想必胜,这三个数最小的两个一定大于等于女队人数的一半;答案就出来了;

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    using namespace std;
    const int INF=0x3f3f3f3f;
    #define mem(x,y) memset(x,y,sizeof(x))
    #define SI(x) scanf("%d",&x)
    #define PI(x) printf("%d",x)
    #define T_T while(T--)
    int main(){
    	int T,N,M,x;
    	SI(T);
    	T_T{
    		SI(N);SI(M);
    		if(M&1)x=3*(M/2);
    		else x=3*(M/2)-1;
    		if(N>=x)puts("Yes");
    		else puts("No");
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    ZOJ Bookcase
    C*++ Calculations
    STL <cctype>
    线段树单点更新+区间更新
    ZOJ Supermarket
    STL <cassert>
    算法导论<二>
    MV Maker [DP]
    LIS 最长有序子序列(递增/递减/非递增/非递减)
    LIS
  • 原文地址:https://www.cnblogs.com/handsomecui/p/5080890.html
Copyright © 2020-2023  润新知