题意:桌子上摆有N种不同类型的球,每种颜色的球有自己的分数值,射中可以得到相应的分数值。规则是每次射击的第一次可以选择任意颜色的球,但是从第二次开始,如果桌子上有红球,就必须先射击红球,射击红球后必须射击一个其他颜色的球。桌子上的球除了红球之外可以在射击掉之后不上相应颜色的球在该位置上,直到桌子上的红球全被射击完,其余颜色的球不再补加,并将桌子上剩余的球全部射击完。最后要求输出一个最大的的分。
思路:我们可以在第一次选择桌子上分数最高的球射击,然后如果有红球就射击红球,红球之后再射击桌子上被补加的分数最高的球,直到红球全部被射击完,这样分数最高的球就被射击了(cnt+1)次,cnt为红球的个数,然后再加上红球的分,加上剩余球的分数,就是最大总分数。
还要注意当桌子上只有红球和没有红球的情况。总结来说全局一共三种可能:
1)cntr==0&&cnto!=0(cntr红球个数,cnto其他颜色的球的个数,除红球)
sum=cnto中每种球的个数乘每种球分数的和。
2)cntr!=0&&cnto==0
sum=1;(红球后必须射击其他颜色的球)
3)cntr!=0&&cnto!=0
sum=(cntr+1)*MaxN(分值最高的球)+cntr+(cnto-2个球的分数总和);
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; struct node { char s[10]; int val; int vis; }p[25]; void Del(node &p1) {///cout<<"fuhzi"<<endl; if(strcmp(p1.s,"red")==0){ p1.val=1;p1.vis=0;} if(strcmp(p1.s,"yellow")==0){ p1.val=2;p1.vis=0;} if(strcmp(p1.s,"green")==0){ p1.val=3;p1.vis=0;} if(strcmp(p1.s,"brown")==0){ p1.val=4;p1.vis=0;} if(strcmp(p1.s,"blue")==0){ p1.val=5;p1.vis=0;} if(strcmp(p1.s,"pink")==0){ p1.val=6;p1.vis=0;} if(strcmp(p1.s,"black")==0){ p1.val=7;p1.vis=0;} return ; } int main() { int n; scanf("%d%*c",&n); int cntr=0,cnto=0; for(int i=0;i<n;i++) { scanf("%s",p[i].s);getchar(); Del(p[i]); if(strcmp(p[i].s,"red")==0) cntr++; else cnto++; }///cout<<"cntr="<<cntr<<"cnto="<<cnto<<endl; // for(int i=0;i<n;i++) // { // printf("%s %d %d\n",p[i].s,p[i].val,p[i].vis); // } int Max=0,k; for(int i=0;i<n;i++){ if(p[i].val>Max){ k=i; Max=p[i].val; } } p[k].vis=1; int sum=0; if(cntr==0&&cnto!=0) {///cout<<"*1"<<endl; for(int i=0;i<n;i++) sum+=p[i].val; } else if(cntr!=0&&cnto==0) {///cout<<"*2"<<endl; sum=1; } else if(cntr!=0&&cnto!=0) {///cout<<"*3"<<endl; sum=Max*(cntr+1)+cntr; for(int i=0;i<n;i++) { if(strcmp(p[i].s,"red")!=0&&!p[i].vis) sum+=p[i].val; } } printf("%d\n",sum); return 0; }