Jxnu Group Programming Ladder Tournament 2017题解

L1-1 这是一道简单题

题解:直接循环输出就好了

1 #include <iostream>
2 using namespace std;
3 int main(){
4     cin.sync_with_stdio(false);
5     for(int i=0;i<3;i++){
6         cout<<"DaHaoGeJiuShiYiGeRuoJi"<<endl;
7     }
8     return 0;
9 }

L1-2 叶神的字符串

题解:查找YS的字符片段,查到了就把它置为空格,遍历完了一遍以后,最后在查找有没有不是空格但是前后相同的转发片段

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 int main(){
 5     string s;
 6     while(cin>>s)
 7     {
 8         int cnt=0;
 9         for(int i=0;i<s.length()-1;i++)
10         {
11             if(s[i]=='Y'&&s[i+1]=='S')
12                 cnt++,s[i]=s[i+1]=' ';
13         }
14         for(int i=0;i<s.length()-1;i++)
15         {
16             if(s[i]!=' '&&s[i]==s[i+1])
17             {
18                 cnt++;
19                 break;
20             }
21         }
22         cout<<cnt<<endl;
23     }
24     return 0;
25 }

L1-3 成绩排名

题解:直接进行结构体排序就好了,处理下相同的分数的排名情况

 1 #include <iostream>
 2 #include <algorithm>
 3 #define N 1010
 4 using namespace std;
 5 struct node{
 6     int id;
 7     int grade[N];
 8     int sum;
 9     string name;
10 }student[N];
11 bool cmp(node a,node b){
12     if(a.sum==b.sum){
13         return a.id<b.id;
14     }
15     return a.sum>b.sum;
16 }
17 int main(){
18     int n,m,num;
19     cin.sync_with_stdio(false);
20     while(cin>>n>>m){
21         for(int i=0;i<n;i++){
22             cin>>student[i].id>>student[i].name;
23             student[i].sum=0;
24             for(int j=0;j<m;j++){
25                 cin>>student[i].grade[j];
26                 student[i].sum+=student[i].grade[j];
27             }
28         }
29         sort(student,student+n,cmp);
30         for(int i=0;i<n;i++){
31             cout<<student[i].id<<" "<<student[i].name;
32             for(int j=0;j<m;j++){
33                 cout<<" "<<student[i].grade[j];
34             }
35             if(i==0){
36                 num=1;
37             }
38             else if(student[i].sum!=student[i-1].sum){
39                 num=i+1;
40             }
41             cout<<" Sum = "<<student[i].sum<<" Ranking = "<<num<<endl;
42         }
43     }
44     return 0;
45 }

L1-4 王胖子买零食

题解:贪心,每次拿最便宜的

 1 #include <iostream>
 2 #include <algorithm>
 3 #define N 1010
 4 using namespace std;
 5 struct node{
 6     int w,m;
 7 }thing[N];
 8 bool cmp(node a,node b){
 9     return a.m<b.m;
10 }
11 int main(){
12     int n,m;
13     cin.sync_with_stdio(false);
14     while(~scanf("%d %d",&n,&m)){
15         for(int i=0;i<m;i++){
16             scanf("%d %d",&thing[i].m,&thing[i].w);
17         }
18         sort(thing,thing+m,cmp);
19         double sum=0;
20         for(int i=0;i<m;i++){
21             if(n>=thing[i].w*thing[i].m){
22                 sum+=thing[i].w;
23                 n-=(thing[i].w*thing[i].m);
24             }
25             else{
26                 sum+=(n*1.0/thing[i].m);
27                 n=0;
28             }
29             if(n==0){
30                 break;
31             }
32         }
33         printf("%.4lf\n",sum);
34     }
35     return 0;
36 }

L1-5 Dada的游戏

题解:遍历整个区间当后一个比前一个大的话就让一个计数器++;当后一个比前一个小的时候,把计数器的值和最大值进行比较并且把计数器置为1,再向后面遍历(PS:因为要连续的所以既然后一个比前一个小,当然就直接从当前去找就好了,回去的话肯定没有有现在最大值的大,所以把i置为j的值)

 1 #include<iostream>
 2 #include<stdio.h>
 3 
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     int n;
 9     int num[100005];
10     while(~scanf("%d",&n))
11     {
12         for(int i = 0; i < n; i++)
13             scanf("%d",&num[i]);
14         int maxx=0,i,j;
15         for(i = 0; i < n-maxx; )
16         {
17             int temp=1;
18             for(j = i+1; j < n; j++)
19             {
20                 if(num[j]>num[j-1])
21                     temp++;
22                 else
23                     break;
24             }
25             if(temp>maxx)
26                 maxx=temp;
27             i=j;//这里要优化要不会超时
28         }
29         printf("%d\n",maxx);
30     }
31     return 0;
32 }

L1-6 

吐槽:一道裸的map的题,后面考虑有人不会stl的map,所以数据开小了直接用数组映射就好了。

题解:把每层的砖块之间的缝的位置算出来放入map中,如果map里原本有的话就在那个值上++,如果没有就在map里新加入一个值为1,最后找map里值最多的,就说明打的洞就是最少的。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <map>
 5 using namespace std;
 6 int main(){
 7     //freopen("in.txt","r",stdin);
 8     //freopen("out.txt","w",stdout);
 9     int n,k;
10 
11     while(scanf("%d",&n)!=EOF)
12     {
13         map<int,int> mp;
14         for(int i=0;i<n;i++)
15         {
16             scanf("%d",&k);
17             int widthCnt=0;
18             int nowWidth;
19             for(int j=0;j<k;j++)
20             {
21                 scanf("%d",&nowWidth);
22                 if(j!=k-1)
23                 {
24                     widthCnt+=nowWidth;
25                     mp[widthCnt]++;
26                 }
27             }
28         }
29         map<int,int>::iterator it;
30         int maxGaps=0;
31         for(it=mp.begin();it!=mp.end();it++)
32             if(maxGaps<it->second)
33                 maxGaps=it->second;
34         printf("%d\n",n-maxGaps);
35     }
36     return 0;
37 }

L2-1 N!

题解:有两种办法,一个是用c++的高精度来写,第二种是用long long int去存乘积,但是不要全部都存,把计算过程中所有的因子10提取出来(PS:sum只存去除后缀0的数),就是说例如如果遇到了5,就把sum除以2,把标志末尾有多少个0的计数器++,最后吧sum输出,在循环输出全部的0。 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <map>
 5 #define LL long long int
 6 using namespace std;
 7 
 8 int main(){
 9     //freopen("in.txt","r",stdin);
10     //freopen("out.txt","w",stdout);
11     LL n;
12     while(cin>>n)
13     {
14         LL pre=1;
15         string s="";
16         for(int i=2;i<=n;i++)
17         {
18             int x=i;
19             while(x%5==0)
20             {
21                 if(x%2==0)
22                     x/=2;
23                 else
24                     pre/=2;
25                 x/=5;
26                 s+='0';
27             }
28             pre*=x;
29         }
30         cout<<pre<<s<<endl;
31 
32     }
33     return 0;
34 }

L2-2 日天的终生大事

题解:

这道题目可以从递推的角度来分析,

对于任何一个L位K进制数,可以由一个L-1位K进制数(这里考虑前导0,因为无论多少前导0,都可以在首部加入非0数字使其合法)在首部加上一个数组合而成。
所以构建递推状态dp[i][j]//表示i位,首部为数字j的数的种类。那么可以推导公式:dp[i][j]=dp[i-1][x]-dp[i-1][j-1]-dp[i-1][j+1] (0<=x<k),此处dp[i-1][x]为x各种取值下的求和。计算完后还得按题目要求去除数字和它相邻的情况。
最后对L位以1~k-1的状态求和即可。
代码还需要处理几个点:
1、做减法后可能为负数,要处理成正数。
2、左右不一定都存在数字,要根据j判断。
3、用循环求和会多出k的复杂度,因为在先前以及依次求出了dp[i-1][x],所以用sum累计一下,直接就可以在求解dp[i][j]时使用。
4、虽然对于大部分数,不能有前导0,所以最后求和时,不考虑dp[L][0],但是对于位数为1时,需要累计dp[1][0]。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <map>
 5 #include <algorithm>
 6 #define LL long long int
 7 using namespace std;
 8 LL dp[1005][1005];
 9 const LL mod=1000000007LL;
10 int main(){
11 
12     //freopen("in.txt","r",stdin);
13     cin.sync_with_stdio(false);
14     LL k,l;
15     while(cin>>k>>l)
16     {
17         LL sum=0;
18         for(int i=0;i<k;i++)
19             dp[1][i]=1,sum++;
20         dp[1][k]=0;
21 
22         for(int i=2;i<=l;i++)
23         {
24             LL temp=0;
25             for(int j=0;j<k;j++)
26             {
27                 dp[i][j]=sum;
28                 if(j==0)
29                     dp[i][j]-=dp[i-1][j+1];
30                 else
31                     dp[i][j]-=(dp[i-1][j-1]+dp[i-1][j+1]);
32                 dp[i][j]=(dp[i][j]+3*mod)%mod;
33                 temp+=dp[i][j];
34                 temp%=mod;
35             }
36             dp[i][k]=0;
37             sum=temp;
38         }
39         sum=0;
40         for(int i=l==1?0:1;i<k;i++)
41         {
42             sum+=dp[l][i],sum%=mod;
43         }
44         cout<<sum<<endl;
45     }
46     return 0;
47

 

2017-05-02 20:44:07

posted @ 2017-05-02 21:10  ガ落涙『不變』  阅读(230)  评论(2编辑  收藏  举报