noip2008题解
背景
笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼。但是他找到了一种方法,经试验证明,用这种方法去选择选项的时候选对的几率非常大!
描述
这种方法的具体描述如下:假设maxn是单词中出现次数最多的字母的出现次数,minn是单词中出现次数最少的字母的出现次数,如果maxn-minn是一个质数,那么笨小猴就认为这是个Lucky Word,这样的单词很可能就是正确的答案。
格式
输入格式
输入只有一行,是一个单词,其中只可能出现小写字母,并且长度小于100。
输出格式
输出共两行,第一行是一个字符串,假设输入的的单词是Lucky Word,那么输出“Lucky Word”,否则输出“No Answer”;
第二行是一个整数,如果输入单词是Lucky Word,输出maxn-minn的值,否则输出0。
限制
各个测试点1s
提示
【输入输出样例1解释】
单词error中出现最多的字母r出现了3次,出现次数最少的字母出现了1次,3-1=2,2是质数。
【输入输出样例2解释】
单词olymipic中出现最多的字母i出现了2次,出现次数最少的字母出现了1次,2-1=1,1不是质数。
模拟找出最多字母最少字母即可
vijos1495
1 #include<stdio.h> 2 #include<string.h> 3 int zhi(int o) 4 { 5 int i,p=0; 6 for(i=2;i<(o/2);i++) 7 if(o%i==0)p=1; 8 if(o==0||o==1)p=1; 9 return p; 10 } 11 int main() 12 { 13 char s[100]; 14 int l,i,a[100]={0},m=0,n=0; 15 scanf("%s",s); 16 for(i=0;i<=strlen(s)-1;i++) 17 for(l=0;l<=strlen(s)-1;l++) 18 if(s[i]==s[l])a[i]++; 19 n=a[1]; 20 for(i=0;i<=strlen(s)-1;i++) 21 { 22 if(a[i]<n)n=a[i]; 23 if(a[i]>m)m=a[i]; 24 } 25 if(zhi(m-n)==0)printf("Lucky Word\n%d",m-n); 26 else printf("No Answer\n0"); 27 return 0; 28 }
描述
给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A、B、C是用火柴棍拼出的整数(若该数非零,则最高位不能是0)。用火柴棍拼数字0-9的拼法如图所示:
注意:
1. 加号与等号各自需要两根火柴棍
2. 如果A≠B,则A+B=C与B+A=C视为不同的等式(A、B、C>=0)
3. n根火柴棍必须全部用上
格式
输入格式
输入共一行,有一个整数n(n<=24)。
输出格式
输出共一行,表示能拼成的不同等式的数目。
限制
1s
提示
【输入输出样例1解释】
2个等式为0+1=1和1+0=1。
【输入输出样例2解释】
9个等式为:
0+4=4
0+11=11
1+10=11
2+2=4
2+7=9
4+0=4
7+2=9
10+1=11
11+0=11
搜索...
vjos1496
1 #include<stdio.h> 2 int main( ) 3 { 4 int n,i,j,t,a[10],t1,i1,j1,add=0; 5 a[0]=6; 6 a[1]=2; 7 a[2]=5; 8 a[3]=5; 9 a[4]=4; 10 a[5]=5; 11 a[6]=6; 12 a[7]=3; 13 a[8]=7; 14 a[9]=6; 15 scanf("%d",&n); 16 for(i=0;i<=2000;i++) 17 for(j=0;j<=2000;j++) 18 { 19 t=i+j; 20 if(t>=1000) t1=a[t/1000]+a[t%10]+a[t%100/10]+a[t%1000/100]; 21 else if(t>=100) t1=a[t/100]+a[t%10]+a[t%100/10]; 22 else if(t>=10) t1=a[t/10]+a[t%10]; 23 else t1=a[t]; 24 25 if(i>=1000) i1=a[i/1000]+a[i%10]+a[i%100/10]+a[i%1000/100]; 26 else if(i>=100) i1=a[i/100]+a[i%10]+a[i%100/10]; 27 else if(i>=10) i1=a[i/10]+a[i%10]; 28 else i1=a[i]; 29 30 31 if(j>=1000) j1=a[j/1000]+a[j%10]+a[j%100/10]+a[j%1000/100]; 32 else if(j>=100) j1=a[j/100]+a[j%10]+a[j%100/10]; 33 else if(j>=10) j1=a[j/10]+a[j%10]; 34 else j1=a[j]; 35 36 if(t1+i1+j1+4==n) add++; 37 t1=0;i1=0;j1=0; 38 } 39 printf("%d",add); 40 41 return 0; 42 }
描述
小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题。一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了。幸运的是,他们可以通过传纸条来进行交流。纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n)。从小渊传到小轩的纸条只可以向下或者向右传递,从小轩传给小渊的纸条只可以向上或者向左传递。
在活动进行中,小渊希望给小轩传递一张纸条,同时希望小轩给他回复。班里每个同学都可以帮他们传递,但只会帮他们一次,也就是说如果此人在小渊递给小轩纸条的时候帮忙,那么在小轩递给小渊的时候就不会再帮忙。反之亦然。
还有一件事情需要注意,全班每个同学愿意帮忙的好感度有高有低(注意:小渊和小轩的好心程度没有定义,输入时用0表示),可以用一个0-100的自然数来表示,数越大表示越好心。小渊和小轩希望尽可能找好心程度高的同学来帮忙传纸条,即找到来回两条传递路径,使得这两条路径上同学的好心程度只和最大。现在,请你帮助小渊和小轩找到这样的两条路径。
格式
输入格式
输入第一行有2个用空格隔开的整数m和n,表示班里有m行n列(1<=m,n<=50)。
接下来的m行是一个m*n的矩阵,矩阵中第i行j列的整数表示坐在第i行j列的学生的好心程度。每行的n个整数之间用空格隔开。
输出格式
输出共一行,包含一个整数,表示来回两条路上参与传递纸条的学生的好心程度之和的最大值。
限制
各个测试点1s
提示
【限制】
30%的数据满足:1<=m,n<=10
100%的数据满足:1<=m,n<=50
1 #include<cstdio> 2 using namespace std; 3 4 int num[55][55],answer[55][55][55][55]; 5 int max(int a,int b) 6 { 7 if(a>b)return a; 8 return b; 9 } 10 int main() 11 { 12 int n,m; 13 scanf("%d%d",&n,&m); 14 for(int i=1;i<=n;i++) 15 for(int j=1;j<=m;j++) 16 scanf("%d",&num[i][j]); 17 for(int i=1;i<=n;i++) 18 for(int j=1;j<=m;j++) 19 for(int k=1;k<=n;k++) 20 for(int l=1;l<=m;l++) 21 if((i!=k||j!=l)||(i==n&&k==n&&j==m&&l==m)) 22 answer[i][j][k][l]=max(answer[i-1][j][k-1][l],max(answer[i-1][j][k][l-1],max(answer[i][j-1][k-1][l],answer[i][j-1][k][l-1])))+num[i][j]+num[k][l]; 23 printf("%d",answer[n][m][n][m]); 24 return 0; 25 }
描述
Tom最近在研究一个有趣的排序问题。如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序。
操作a
如果输入序列不为空,将第一个元素压入栈S1
操作b
如果栈S1不为空,将S1栈顶元素弹出至输出序列
操作c
如果输入序列不为空,将第一个元素压入栈S2
操作d
如果栈S2不为空,将S2栈顶元素弹出至输出序列
如果一个1~n的排列P可以通过一系列操作使得输出序列为1,2,…,(n-1),n,Tom就称P是一个“可双栈排序排列”。例如(1,3,2,4)就是一个“可双栈排序序列”,而(2,3,4,1)不是。
将(1,3,2,4)排序的操作序列:<a,c,c,b,a,d,d,b>
当然,这样的操作序列有可能有几个,对于上例(1,3,2,4),<a,c,c,b,a,d,d,b>是另外一个可行的操作序列。
Tom希望知道其中字典序最小的操作序列是什么。
格式
输入格式
第一行是一个整数n。
第二行有n个用空格隔开的正整数,构成一个1~n的排列。
输出格式
输出文件共一行,如果输入的排列不是“可双栈排序排列”,输出数字0;
否则输出字典序最小的操作序列,每两个操作之间用空格隔开,行尾没有空格。
限制
1s
提示
30%的数据满足: n<=10
50%的数据满足: n<=50
100%的数据满足: n<=1000
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstdlib> 4 #include<string.h> 5 #include<algorithm> 6 #define N 1005 7 using namespace std; 8 int n,number[N]; 9 int beg[N]; 10 int cnt; 11 int nowmin[N]; 12 int mark[N]; 13 int flag[N]; 14 15 class Stack 16 { 17 private: 18 int rear; 19 int stack[N]; 20 public: 21 Stack() 22 { 23 rear=-1; 24 } 25 int Destack() 26 { 27 int x=stack[rear]; 28 rear--; 29 return x; 30 } 31 void Enstack(int x) 32 { 33 rear++; 34 stack[rear]=x; 35 } 36 int Getrear() 37 { 38 return stack[rear]; 39 } 40 int Getsize() 41 { 42 return rear; 43 } 44 }s[2]; 45 46 struct edge 47 { 48 int b,next; 49 }E[N]; 50 51 void addedge(int a,int b) 52 { 53 E[cnt].b=b; 54 E[cnt].next=beg[a]; 55 beg[a]=cnt; 56 cnt++; 57 E[cnt].b=a; 58 E[cnt].next=beg[b]; 59 beg[b]=cnt; 60 cnt++; 61 } 62 63 int DFS(int now,int deep) 64 { 65 if(flag[now]!=-1&&flag[now]!=deep%2) 66 return 0; 67 flag[now]=deep%2; 68 for(int i=beg[now];i!=-1;i=E[i].next) 69 { 70 if(flag[E[i].b]==(deep+1)%2) 71 continue; 72 if(DFS(E[i].b,deep+1)==0) 73 return 0; 74 } 75 return 1; 76 } 77 78 int main() 79 { 80 memset(beg,-1,sizeof(beg)); 81 scanf("%d",&n); 82 for(int i=0;i<n;i++) 83 scanf("%d",&number[i]); 84 nowmin[n-1]=number[n-1]; 85 for(int i=n-2;i>=0;i--) 86 nowmin[i]=min(nowmin[i+1],number[i]); 87 for(int i=0;i<n-1;i++) 88 for(int j=i+1;j<n-1;j++) 89 if(nowmin[j+1]<number[i]&&number[i]<number[j]) 90 addedge(i,j); 91 memset(mark,-1,sizeof(mark)); 92 memset(flag,-1,sizeof(flag)); 93 for(int i=0;i<n;i++) 94 if(mark[i]==-1) 95 { 96 if(DFS(i,0)==0) 97 { 98 printf("0\n"); 99 return 0; 100 } 101 for(int i=0;i<n;i++) 102 if(flag[i]!=-1) 103 mark[i]=flag[i]; 104 memset(flag,-1,sizeof(flag)); 105 } 106 int now=1; 107 for(int i=0;i<n;i++) 108 { 109 while(1) 110 { 111 int mar=0; 112 if(s[0].Getsize()!=-1&&s[0].Getrear()==now) 113 { 114 s[0].Destack(); 115 now++; 116 printf("b "); 117 mar=1; 118 } 119 if(s[1].Getsize()!=-1&&s[1].Getrear()==now) 120 { 121 s[1].Destack(); 122 now++; 123 printf("d "); 124 mar=1; 125 } 126 if(mar==0) 127 break; 128 } 129 s[mark[i]].Enstack(number[i]); 130 if(mark[i]==0) 131 printf("a "); 132 else printf("c "); 133 } 134 while(1) 135 { 136 int mar=0; 137 if(s[0].Getsize()!=-1&&s[0].Getrear()==now) 138 { 139 s[0].Destack(); 140 now++; 141 printf("b "); 142 mar=1; 143 } 144 if(s[1].Getsize()!=-1&&s[1].Getrear()==now) 145 { 146 s[1].Destack(); 147 now++; 148 printf("d "); 149 mar=1; 150 } 151 if(mar==0) 152 break; 153 } 154 return 0; 155 }