Jxnu Group Programming Ladder Tournament 2017题解

来源:互联网 发布:喷涂机器人及软件编程 编辑:程序博客网 时间:2024/06/04 23:29
L1-1 这是一道简单题

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

#include <iostream>using namespace std;int main(){    cin.sync_with_stdio(false);    for(int i=0;i<3;i++){        cout<<"DaHaoGeJiuShiYiGeRuoJi"<<endl;    }    return 0;}

L1-2 叶神的字符串

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

#include <iostream>#include <string>using namespace std;int main(){    string s;    while(cin>>s)    {        int cnt=0;        for(int i=0;i<s.length()-1;i++)        {            if(s[i]=='Y'&&s[i+1]=='S')                cnt++,s[i]=s[i+1]=' ';        }        for(int i=0;i<s.length()-1;i++)        {            if(s[i]!=' '&&s[i]==s[i+1])            {                cnt++;                break;            }        }        cout<<cnt<<endl;    }    return 0;}

L1-3 成绩排名

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

#include <iostream>#include <algorithm>#define N 1010using namespace std;struct node{    int id;    int grade[N];    int sum;    string name;}student[N];bool cmp(node a,node b){    if(a.sum==b.sum){        return a.id<b.id;    }    return a.sum>b.sum;}int main(){    int n,m,num;    cin.sync_with_stdio(false);    while(cin>>n>>m){        for(int i=0;i<n;i++){            cin>>student[i].id>>student[i].name;            student[i].sum=0;            for(int j=0;j<m;j++){                cin>>student[i].grade[j];                student[i].sum+=student[i].grade[j];            }        }        sort(student,student+n,cmp);        for(int i=0;i<n;i++){            cout<<student[i].id<<" "<<student[i].name;            for(int j=0;j<m;j++){                cout<<" "<<student[i].grade[j];            }            if(i==0){                num=1;            }            else if(student[i].sum!=student[i-1].sum){                num=i+1;            }            cout<<" Sum = "<<student[i].sum<<" Ranking = "<<num<<endl;        }    }    return 0;}

L1-4 王胖子买零食

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

 #include <iostream>#include <algorithm>#define N 1010using namespace std;struct node{    int w,m;}thing[N];bool cmp(node a,node b){    return a.m<b.m;}int main(){    int n,m;    cin.sync_with_stdio(false);    while(~scanf("%d %d",&n,&m)){        for(int i=0;i<m;i++){            scanf("%d %d",&thing[i].m,&thing[i].w);        }        sort(thing,thing+m,cmp);        double sum=0;        for(int i=0;i<m;i++){            if(n>=thing[i].w*thing[i].m){                sum+=thing[i].w;                n-=(thing[i].w*thing[i].m);            }            else{                sum+=(n*1.0/thing[i].m);                n=0;            }            if(n==0){                break;            }        }        printf("%.4lf\n",sum);    }    return 0;}

L1-5 Dada的游戏

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

 #include<iostream>#include<stdio.h>using namespace std;int main(){    int n;    int num[100005];    while(~scanf("%d",&n))    {        for(int i = 0; i < n; i++)            scanf("%d",&num[i]);        int maxx=0,i,j;        for(i = 0; i < n-maxx; )        {            int temp=1;            for(j = i+1; j < n; j++)            {                if(num[j]>num[j-1])                    temp++;                else                    break;            }            if(temp>maxx)                maxx=temp;            i=j;//这里要优化要不会超时        }        printf("%d\n",maxx);    }    return 0;}

L1-6 

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

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

 #include <iostream>#include <cstdio>#include <vector>#include <map>using namespace std;int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int n,k;    while(scanf("%d",&n)!=EOF)    {        map<int,int> mp;        for(int i=0;i<n;i++)        {            scanf("%d",&k);            int widthCnt=0;            int nowWidth;            for(int j=0;j<k;j++)            {                scanf("%d",&nowWidth);                if(j!=k-1)                {                    widthCnt+=nowWidth;                    mp[widthCnt]++;                }            }        }        map<int,int>::iterator it;        int maxGaps=0;        for(it=mp.begin();it!=mp.end();it++)            if(maxGaps<it->second)                maxGaps=it->second;        printf("%d\n",n-maxGaps);    }    return 0;}

L2-1 N!

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

 #include <iostream>#include <cstdio>#include <vector>#include <map>#define LL long long intusing namespace std;int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    LL n;    while(cin>>n)    {        LL pre=1;        string s="";        for(int i=2;i<=n;i++)        {            int x=i;            while(x%5==0)            {                if(x%2==0)                    x/=2;                else                    pre/=2;                x/=5;                s+='0';            }            pre*=x;        }        cout<<pre<<s<<endl;    }    return 0;}

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]。

 #include <iostream>#include <cstdio>#include <vector>#include <map>#include <algorithm>#define LL long long intusing namespace std;LL dp[1005][1005];const LL mod=1000000007LL;int main(){    //freopen("in.txt","r",stdin);    cin.sync_with_stdio(false);    LL k,l;    while(cin>>k>>l)    {        LL sum=0;        for(int i=0;i<k;i++)            dp[1][i]=1,sum++;        dp[1][k]=0;        for(int i=2;i<=l;i++)        {            LL temp=0;            for(int j=0;j<k;j++)            {                dp[i][j]=sum;                if(j==0)                    dp[i][j]-=dp[i-1][j+1];                else                    dp[i][j]-=(dp[i-1][j-1]+dp[i-1][j+1]);                dp[i][j]=(dp[i][j]+3*mod)%mod;                temp+=dp[i][j];                temp%=mod;            }            dp[i][k]=0;            sum=temp;        }        sum=0;        for(int i=l==1?0:1;i<k;i++)        {            sum+=dp[l][i],sum%=mod;        }        cout<<sum<<endl;    }    return 0;}

 

2017-05-02 20:44:07