2018杭电ACM集训队单人排位赛 - 2

Problem A Welcome to the Collegiate Programming Contest

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 102    Accepted Submission(s): 82


Problem Description
Welcome to take part in the first Guangxi Province Collegiate Programming Contest hold by Guilin University of Electronic Technology. Programming contest is a contest played by three programmers with one computer to solve some coding problems. Here you need to solve n problems and you certainly wish to AC them all. The contest begins!
 

Input
The first line is an integer T which indicates the case number.
And as for each case,  there will be one line.
there is an integer n, which indicates the number of problems of this contest.
It is guaranteed that——
T is about 100,
for 100% cases, 1 <= n <= 20.
 

Output
As for each case, you need to output a single line.
There should be n “AC” in the line separated by n – 1 blanks, as it is shown in the sample.
Please notice that you shouldn’t print extra blank even in the end of the line.
 

Sample Input
 
  
234
 

Sample Output
 
  
AC AC ACAC AC AC AC
 
#include<bits/stdc++.h>
using namespace std;

int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=0; i<n-1; i++)printf("AC ");
        printf("AC\n");
    }
    return 0;
}

Problem B Practice

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 96    Accepted Submission(s): 79


Problem Description
Luras is a contestant of the Guangxi Province Collegiate Programming Contest. And she needs to practice before the contest. It is known that there are n problems in her to do list and every problem has its AC time and AC value. Remember, for each problem, only if Luras has spent all the AC time will she gain the AC value. Now there will be m time to practice. Luras could choose way A: solve problems from shorter AC time to longer AC time; or choose way B: solve problems from bigger value to smaller value. In both way, she must stop practicing once she meets a problem which she could not finish. Now could you tell Luras which way should she choose to gain more AC value during time m?
 

Input
The first line is an integer T which indicates the case number.
And as for each case,  there will be 3 lines.
In the first line, there are 2 integers n m, which indicates the number of to do list problems, the practice time respectively.
In the second line, there are n positive integers which is the array a[] representing the AC time array.
In the third line, there are n positive integers which is the array b[] representing the AC value array.
It is guaranteed that——
T is about 100
for 100% cases, 1 <= n <= 4, 1 <= m <= 100, 1 <= a[i], b[i] <= 20
And it is guaranteed for any i and j (i != j), a[i] != a[j] and b[i] != b[j].
 

Output
As for each case, you need to output a single line.
You need to print “A” if only the way A is better;
You need to print “B” if only the way B is better;
You need to print “SAME” if way A is as good as way B.
 

Sample Input
 
   
33 51 2 31 2 33 41 2 33 4 53 41 2 33 2 1
 

Sample Output
 
   
BASAME
 

水题

#include<bits/stdc++.h>
using namespace std;

struct node{
    int t,v;
}a[10];
int cmp1(node a,node b)
{
    return a.t<b.t;
}
int cmp2(node a,node b)
{
    return a.v>b.v;
}

int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        int n,m;int cnt,x=0,y=0;
        scanf("%d%d",&n,&m);
        for(int i=0; i<n; i++)scanf("%d",&a[i].t);
        for(int i=0; i<n; i++)scanf("%d",&a[i].v);
        sort(a,a+n,cmp1);
        cnt=m;
        for(int i=0; i<n; i++)
        {
            cnt-=a[i].t;
            if(cnt>=0)x+=a[i].v;
        }
        sort(a,a+n,cmp2);
        cnt=m;
        for(int i=0; i<n; i++)
        {
            cnt-=a[i].t;
            if(cnt>=0)y+=a[i].v;
        }
        if(x>y)puts("A");
        else if(x<y)puts("B");
        else puts("SAME");
    }
    return 0;
}

Problem C Team Match

Time Limit: 2000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 151    Accepted Submission(s): 51


Problem Description
The programming competition not only depends on the programmers, but also directed by the coaches. Mr Z is a coach who direct n players to take part in the Guangxi Province Collegiate Programming Contest. We assume that a team is consisted of 3 players whose ability is x, y, z respectively and x >= y >= z. Then the team’s total ability is 3 * x + 2 * y + 1 * z; And for a team, if its ability is not lower than the gold medal level m, the team will certainly win the gold medal. Mr Z would like to match teams to gain as many gold medals as possible, could you tell him how many gold medals it is?
 

Input
The first line is an integer T which indicates the case number.
And as for each case,  there will be 2 lines.
In the first line, there are 2 integers n m, which indicate the number of players, the gold medal level respectively. Please remember n is always the multiple of 3.
In the second line, there are n integers which represents everyone’s ability.
It is guaranteed that——
T is about 100.
for 100% cases, 1 <= n <= 15, 1 <= m <= 30, 1 <= a[i] <= 20.
 

Output
As for each case, you need to output a single line.
There should be an integer in the line which means the gold medal teams Mr Z could match.
 

Sample Input
 
   
26 183 3 3 4 2 26 71 1 1 1 1 1
 

Sample Output
 
   
20  
解析:暴力枚举,最优情况就是最大的和最小的去匹配。排个序,从最大的开始往下枚举,记录当前。继续往下枚举,要是
满足就更新记录,直到 不能枚举为止,时候就是最优的=情况了。
  
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    int t,n,m;
    int a[30],vis[30];
    scanf( "%d", &t );
    while ( t-- )
    {
        scanf( "%d%d", &n, &m );
        for(int i=0;i<n;i++ ) scanf( "%d", &a[i] );
        sort(a,a+n,cmp);
        memset(vis,0,sizeof(vis));
        int sum=0;
        for(int i=0;i<n;i++)
        {
            if( vis[i]==1 ) continue;
            int x=-1,y=-1,z=-1;
            for(int j=i+1;j<n;j++)
            {
                if( vis[j]==1 ) continue;
                for(int k=j+1;k<n;k++)
                {
                    if( vis[k]==1 )continue;
                    if( 3*a[i]+2*a[j]+a[k]>=m )
                    {
                        x=i; y=j; z=k;
                    }
                }
            }
            if( x==-1 ) break;
            vis[x]=vis[y]=vis[z]=1;
            sum++;
        }
        printf( "%d\n", sum );
    }
    return 0;
}

Problem D Team Name

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 122    Accepted Submission(s): 64


Problem Description
After all the teams have been matched, what to do next is of course to think about a nice team name. Now it is known that there are n teams taking part in the Guangxi Province Collegiate Programming Contest. And the name of every team is a string consists of English lower characters. Now Luras needs to get her team name, she doesn’t want the name be any consecutive substring of any other teams. And she prefers shorter names. If there are many choices with the shortest length, she would prefer the one which is the smallest lexicographically. Now could you decide the team name for her? We regard string a is lexicographically smaller than string b if there exists such index j that a[i] == b[i] for all i < j and a[j] < b[j].
 

Input
The first line is an integer T which indicates the case number.
And as for each case,  there will be n + 1 lines.
In the first line, there is one integer n, which indicates the number of teams.
Then there will be n strings of the next n lines, indicate the name of every team in each line.
It is guaranteed that—— 
T is about 100.
for 100% cases, 1 <= n <= 100, 1 <= |s|(the length of s)<= 30.
 

Output
As for each case, you need to output a single line.
There should be one string in the line which means the name Luras will give to her team.
 

Sample Input
 
  
2
3
a
b
c
2
abcdefghijklmnopqrstuvwxyz
aa
 

Sample Output
 
  
d
ac
 解析:构造字典序字符串,从小开始构造。一边构造一边和字符串比较,是否是子串。
#include<bits/stdc++.h>
using namespace std;

int n,f;
char s[105][35],a[35],ans[35];
void dfs(int x,int l)
{
	if(f)return ;
	if(x==l)
	{
		a[x]='\0';
		int ff=1;
		for(int i=0; i<n; i++)
		{
			if(strstr(s[i],a))
			{
				ff=0;break;
			}
		}
		if(ff)
		{
			f=1;
			strcpy(ans,a);
		}
		return ;
	}
	for(int i=0; i<26; i++)
	{
		a[x]=i+'a';
		dfs(x+1,l);
	}
}
int main()
{
	int t;scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		for(int i=0; i<n; i++)
		{
			scanf(" %s",s[i]);
		}
		
		f=0;
		for(int i=1; i<=30; i++)
		{
			dfs(0,i);
			if(f)break;
		}
		printf("%s\n",ans);
	}
	return 0;
}

Problem E Travel

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 138    Accepted Submission(s): 66


Problem Description
It is said Guilin's scenery is the best in the world. Now since the first Guangxi Province Collegiate Programming Contest is held in Guilin, Luras decided to travel around Guilin. She knows that there will be n nodes in the travel map. Luras will pick a shortest way to go from node 1 to node n. You are a city designer who could decide if there is a bi-directional edge with the length of 1 between every two nodes. And you hope to build the roads to make the shortest path from 1 to n to be as many as possible. Could you tell Luras how many shortest path could it be at most between node 1 and node n in your final city graph?
 

Input
The first line is an integer T which indicates the case number.
And as for each case,  there will be one lines
In the line, there is 1 integer n, which indicates the number of node.
It is guaranteed that——
T is about 100.
for 100% cases, 2 <= n <= 40.
 

Output
As for each case, you need to output a single line.
There should be one integer in the line which means the maximum shortest path could be between node 1 and node n.
 

Sample Input
 
  
6 2 3 4 5 6 7
 

Sample Output
 
  
1 1 2 3 4 6
 

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int qpow(int a,int b)
{
    int ans=1;
    while ( b)
    {
        if( b&1 ) ans=ans*a;
        a=a*a;
        b/=2;
    }
    return ans;
}
int main()
{
    int n,t;
    scanf( "%d", &t );
    while ( t-- )
    {
        scanf( "%d", &n );
        n-=2;
        int ans;
        if( n<=4 ) printf( "%d\n",n?n:1);
        else
        {
            int k=n/3;
            if( n%3==0 )
                ans=qpow(3,k);
            else if( n%3==2 )
                ans=qpow(3,k)*2;
            else ans=qpow(3,k-1)*4;
            printf( "%d\n",ans );
        }
    }
    return 0;
}

Problem G Balloons

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 153    Accepted Submission(s): 46


Problem Description
The competition is going. Besides the players, volunteers are busy too, they need to send colorful balloons to the contestants. It is known that the contestants are in a huge room of cartesian coordinate system whose seats are 1000 rows multiplying 1000 columns. Every seat could be empty or corresponds to a team. For every minute, volunteers should send all the balloons together. The volunteers will be told where to send each balloon to. They would like to work efficiently. For two positions (r1, c1) and (r2, c2), if the absolute value of (x1 - x2) is not bigger than k or the absolute value of (y1 – y2) is not bigger than k, the two balloons will be sent by a same volunteer. Could you decide how many volunteers are needed at least to send all the balloons?
 

Input
The first line is an integer T which indicates the case number.
And as for each case,  there will be n + 1 lines.
In the first line, there are 2 integers n k, which indicates the number of balloons and the value k.
Then there will be n lines, in every line, there are 2 integers r c which means this balloon will be sent to the r-th row and the c-th column. Please notice that the position could be the same.
It is guaranteed that——
T is about 100.
for 100% cases, 1 <= n <= 10000, 
1 <= k, r, c<= 1000.
 

Output
As for each case, you need to output a single line.
There should be one integer in the line which means the minimum volunteers are needed.
 

Sample Input
 
  
2 3 5 1 1 10 6 15 20 2 5 1 1 7 7
 

Sample Output
 
  
1 2

题意不多讲。解析:我们要想要最少的志愿者,那么务必就是要x的差和y的差两个差要越小,所以我们排个序,这样就是可以差值最小。那么我们怎么记录满足条件的他们呢!用并查集把他们归并到同一个根节点。最后有几个集合就是所求的最小志愿者的人数。

#include<bits/stdc++.h>
using namespace std; 
const int maxn=10005;
int n,k,r,c;
int f[maxn];
struct node{
	int x,y,id;
}a[maxn];
int cmp(node a,node b)
{
	return a.x<b.x;
}
int cmp2(node a,node b)
{
	return a.y<b.y;
}

int Find(int x)
{
	return x==f[x]?x:Find(f[x]);
}
int main()
{
	int t;scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&k);
		for(int i=0; i<n; i++)f[i]=i;
		for(int i=0; i<n; i++)
		{
			scanf("%d%d",&a[i].x,&a[i].y);
			a[i].id=i;
		}
		sort(a,a+n,cmp);
		for(int i=1; i<n; i++)
		{
			if(a[i].x-a[i-1].x<=k)
			{
				int x=Find(a[i].id);
				int y=Find(a[i-1].id);
				if(x!=y)f[x]=y;	
			}
		}
		sort(a,a+n,cmp2);
		for(int i=1; i<n; i++)
		{
			if(a[i].y-a[i-1].y<=k)
			{
				int x=Find(a[i].id);
				int y=Find(a[i-1].id);
				if(x!=y)f[x]=y;	
			}
		}
		int cnt=0;
		for(int i=0; i<n; i++)
		{
			if(i==f[i])cnt++;
		}
		printf("%d\n",cnt);
	}
	return 0;
}

Problem H Board

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 82    Accepted Submission(s): 78


Problem Description
The contest has finished. The work turns into the host now. he needs to read all teams’ names later. We suppose the teams’ names are all single string with only English Characters. Could you help the host to calculate how many English characters should he read in total?
 

Input
The first line is an integer T which indicates the case number.
And as for each case,  there will be n + 1 lines.
In the first line, there is 1 integer n, which indicates the number of teams.
Then there will be n strings of the next n lines, indicate the name of every team in each line.
It is guaranteed that——
T is about 100,
for 100% cases, 1 <= n <= 100, 1 <= |s|(the length of s)<= 30.
 

Output
As for each case, you need to output a single line.
There should be one integer in the line which means the total number of English characters of all teams.
 

Sample Input
 
   
2 3 a bb ccc 2 ChikenDinner NoResponse
 

Sample Output
 
   
6 22
 
水题......
#include<bits/stdc++.h>
using namespace std;

int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        char s[35];
        int n;int cnt=0;
        scanf("%d",&n);
        for(int i=0; i<n; i++)
        {
            scanf(" %s",s);
            cnt+=strlen(s);
        }
        
        printf("%d\n",cnt);
    }
    return 0;
}

Problem I Rank LED

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 94    Accepted Submission(s): 32


Problem Description
The host has released the rank. Everyone’s rank is shown in the LED screen as our Picture. 

You could see the light line of number for ‘0’ to ‘9’ is {6、2、5、5、4、5、6、3、7、6} in the order. Luras would like to modify the position of every light line to make her new rank as small as possible while the new rank is also a positive integer without any leading zeros. What’s more, the total number of light lines should be as same as the beginning. Could you tell Luras what the best result she could modify to?
 

Input
The first line is an integer T which indicates the case number.
And as for each case,  there will be 2 lines.
There is an integer n in the first line which is the length of the number string.
The 2nd line is a number string which is a non-leading zero big positive integer of length n.
It is guaranteed that——
T is about 100.
for 100% cases, 1 <= n <= 100. strings are all non-leading zero number strings.
 

Output
As for each case, you need to output a single line.
There should be one non-leading zero positive number string in the line which means the best rank Luras could modify to.
 

Sample Input
 
  
3 1 9 2 99 5 10000
 

Sample Output
 
  
6 28 2888
 

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int main(){
    int n,i,k,t;
    char s[110];
    int b[]={6,2,5,5,4,5,6,3,7,6};
    int a[]={0,0,1,7,4,2,6,8,10,18,22,20,28,68,88,108,188,200,208,288,688,888};
    scanf( "%d", &t );
    while ( t-- )
    {
        scanf( "%d%s",&n,s);
        int sum=0;
        for(int i=0;i<n;i++)
            sum+=b[s[i]-'0'];
        if(sum<=21) printf("%d\n",a[sum]);
        else
        {
           printf("%d",a[(sum%7)+14]);
           k=sum/7-2;
           for(i=0;i<k;i++) printf("8");
            printf("\n");
        }
    }
    return 0;
}

Problem J Pot

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 115    Accepted Submission(s): 74


Problem Description
The rank has been released. Luras is unhappy because she has not achieved her desired result. So she wants to throw her responsibility to her teammates, so it is the same with her teammates, they would also throw their responsibility to her. There are n members of her team, each has committed a certain degree of mistakes which is called "pot." And the severity of the error is called the size of the "pot." If the pot sizes of A and B are x and y respectively (we assume x > y), then A can divert attention by blaming B, making the size of his pot becoming x – y instead of x. 
As it is a team, every member would cooperate together to throw their pots in the best orderly way to make the sum of all pots to be as small as possible. Could you help her calculate what the sum is?
 

Input
The first line is an integer T which indicates the case number.
And as for each case,
the first line is an integer n which indicates the number of people in her team,
the second line contains n positive integers, which indicates the size of the pot of each person.
It is guaranteed that——
T is less than 100,
for 100% cases, 1 <= n <= 100. 
1 <= the size of the pot of each person <= 100.
 

Output
As for each case, you need to output a single line.
There should be only one integer in the line which indicates the minimum&#160;sum&#160;of&#160;all&#160;pots in the end.
 

Sample Input
 
  
5 3 2 4 6 2 12 18 5 45 12 27 30 18 2 1 2 1 9
 

Sample Output
 
  
6 12 15 2 9
 
解析:我们可以发现想到,最后互相减去后都会变成同一个数(有1的情况就是最后都变成1),起先以为是什么贪心或者平均值

什么的。原来是辗转相除法(也就是求最大公约数)。为什么是辗转相除法呢?

辗转相除法就是一个大的数%小的数,然后把余数赋值给大的数。题目就是把大的数减去小的数,然后差值就是辗转相除法的余数。因为最后都是变成了同一个数,也就是这些数我们一直相减(取余),这过程就是辗转相除的过程,得到的数就是公约数。

.......这题寝室数据不大,还是可以暴力过的。

#include<bits/stdc++.h>
using namespace std;
int gcd(int a,int b)
{
    return b==0?a:gcd(b,a%b);
}
int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        int f=0;
        int a[1005];
        int n;scanf("%d",&n);
        for(int i=0; i<n; i++)
        {
            scanf("%d",&a[i]);
            if(a[i]==1)f=1;
        }
        if(n==1)
        {
            printf("%d\n",a[0]);
            continue;
        }
        if(f)
        {
            printf("%d\n",n);continue;
        }
        int k=a[0];
        for(int i=1; i<n; i++)
        {
            k=gcd(k,a[i]);
        }
        printf("%d\n",k*n);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yu121380/article/details/81052979
今日推荐