A:吃糖果
-
总时间限制:
- 1000ms 内存限制:
- 65536kB
-
描述
- 名名的妈妈从外地出差回来,带了一盒好吃又精美的巧克力给名名(盒内共有 N 块巧克力,20 > N >0)。妈妈告诉名名每天可以吃一块或者两块巧克力。假设名名每天都吃巧克力,问名名共有多少种不同的吃完巧克力的方案。例如:如果N=1,则名名第1天就吃掉它,共有1种方案;如果N=2,则名名可以第1天吃1块,第2天吃1块,也可以第1天吃2块,共有2种方案;如果N=3,则名名第1天可以吃1块,剩2块,也可以第1天吃2块剩1块,所以名名共有2+1=3种方案;如果N=4,则名名可以第1天吃1块,剩3块,也可以第1天吃2块,剩2块,共有3+2=5种方案。现在给定N,请你写程序求出名名吃巧克力的方案数目。 输入
- 输入只有1行,即整数N。 输出
- 输出只有1行,即名名吃巧克力的方案数。 样例输入
-
4
样例输出
5
/*一个裸裸的斐波那契数列*/ #include<cstdio> #include<iostream> using namespace std; int n; long long int f[30]; int main() { scanf("%d",&n); f[1]=1; f[2]=2; for(int i=3;i<=n;++i) f[i]=f[i-1]+f[i-2]; printf("%d\n",f[n]); return 0; }
B:话题焦点人物
-
总时间限制:
- 1000ms 内存限制:
- 65536kB
-
描述
-
微博提供了一种便捷的交流平台。一条微博中,可以提及其它用户。例如Lee发出一条微博为:“期末考试顺利 @Kim @Neo”,则Lee提及了Kim和Neo两位用户。
我们收集了N(1 < N < 10000)条微博,并已将其中的用户名提取出来,用小于100的正整数表示。
通过分析这些数据,我们希望发现大家的话题焦点人物,即被提及最多的人(题目保证这样的人有且只有一个),并找出那些提及它的人。
输入
-
输入共两部分:
第一部分是微博数量N,1 < N < 10000。
第二部分是N条微博,每条微博占一行,表示为:
发送者序号a,提及人数k(0 < = k < = 20),然后是k个被提及者序号b1,b2...bk;
其中a和b1,b2...bk均为大于0小于100的整数。相邻两个整数之间用单个空格分隔。
输出
-
输出分两行:
第一行是被提及最多的人的序号;
第二行是提及它的人的序号,从小到大输出,相邻两个数之间用单个空格分隔。同一个序号只输出一次。
样例输入
-
5 1 2 3 4 1 0 90 3 1 2 4 4 2 3 2 2 1 3
样例输出
3
1 2 4
/*直接模拟:*/ #include<iostream> using namespace std; #include<cstdio> #include<algorithm> #define N 10001/*这里为什么要把N开到10000这么大呢?考虑题目中的特殊数据,一开始我开到200,就过了8个点。 特殊数据:一万个微博 都提及了一个人,那么这个人的pre数据就要储存一万个人的信息,虽然最后还会去重,但是这时候确实很有可鞥越界 */ int pre[201][N],ans[2],sum[201]; int n,a,k,b; void input() { scanf("%d",&n); for(int i=1;i<=n;++i) { scanf("%d%d",&a,&k); for(int i=1;i<=k;++i) { scanf("%d",&b); sum[b]++;/*统计每个人被提及的次数*/ if(sum[b]>ans[1])/*随时计入最大值*/ { ans[1]=sum[b]; ans[0]=b; } pre[b][0]++;/*记录提及b的人数和人的编号*/ pre[b][pre[b][0]]=a; } } } void chuli() { int an=ans[0]; printf("%d\n",ans[0]); sort(pre[an]+1,pre[an]+pre[an][0]+1);/*这是题目中说的按照序号由小到大输出*/ int p=0; for(int i=1;i<=pre[an][0];++i) { if(pre[an][i]!=p)/*输出时去重,相同的不输出,不同与p的输出,并且更新p,因为序列是升序的,所以这个方法可行*/ { printf("%d ",pre[an][i]); p=pre[an][i]; } else continue; } } int main() { input(); chuli(); return 0; }
C:完美立方
-
总时间限制:
- 1000ms 内存限制:
- 65536kB
-
描述
-
形如a3= b3 + c3 + d3的等式被称为完美立方等式。例如123= 63 + 83 + 103 。编写一个程序,对任给的正整数N (N≤100),寻找所有的四元组(a, b, c, d),使得a3 = b3 + c3 + d3,其中a,b,c,d 大于 1, 小于等于N,且b<=c<=d。
输入
- 一个正整数N (N≤100)。 输出
-
每行输出一个完美立方。输出格式为:
Cube = a, Triple = (b,c,d)
其中a,b,c,d所在位置分别用实际求出四元组值代入。
请按照a的值,从小到大依次输出。当两个完美立方等式中a的值相同,则b值小的优先输出、仍相同则c值小的优先输出、再相同则d值小的先输出。
样例输入
-
24
样例输出
-
Cube = 6, Triple = (3,4,5) Cube = 12, Triple = (6,8,10) Cube = 18, Triple = (2,12,16) Cube = 18, Triple = (9,12,15) Cube = 19, Triple = (3,10,18) Cube = 20, Triple = (7,14,17) Cube = 24, Triple = (12,16,20)
#include<iostream> using namespace std; #include<cstdio> int n; int main() { scanf("%d",&n); for(int i=2;i<=n;++i) for(int j=2;j<=n;++j) for(int k=2;k<=n;++k) for(int l=2;l<=n;++l) { if(j<=k&&k<=l&&i*i*i==j*j*j+k*k*k+l*l*l) printf("Cube = %d, Triple = (%d,%d,%d)\n",i,j,k,l); } return 0; }
D:478-3279
-
总时间限制:
- 1000ms 内存限制:
- 65536kB
-
描述
-
在美国,商家都喜欢用好记的电话号码。人们常用的方法就是把电话号码拼成一个便于记忆的词汇或者短语,比如你可以通过Gino比萨店的电话号码301- GINO来定比萨。另一个方法就是把电话号码分为成组的数字,比如你可以通过必胜客的电话“三个十”:3-10-10-10来定比萨。
一个七位电话号码的标准形式是xxx-xxxx,如 123-4567。
通常,电话上的数字与字母的映射关系如下
A, B, C 映射到 2
D, E, F 映射到 3
G, H, I 映射到 4
J, K, L映射到5
M, N, O映射到6
P, R, S映射到7
T, U, V映射到8
W, X, Y映射到9
Q和Z并没有相关的映射。
你的任务就是把一个七位电话号码转为标准的xxx-xxxx格式,其中x表示数字
输入
- 第一行为输入的电话号码个数n(n < 100), 下面n行每行表示一个七位号码,这些号数为了便于记忆可能不是标准格式,但一定是合法的。 输出
- 对于行输入,输出一个标准格式的电话号码 样例输入
-
12 4873279 ITS-EASY 888-4567 3-10-10-10 888-GLOP TUT-GLOP 967-11-11 310-GINO F101010 888-1200 -4-8-7-3-2-7-9- 487-3279
样例输出
-
487-3279 487-3279 888-4567 310-1010 888-4567 888-4567 967-1111 310-4466 310-1010 888-1200 487-3279 487-3279
/*A, B, C 映射到 2 D, E, F 映射到 3 G, H, I 映射到 4 J, K, L映射到5 M, N, O映射到6 P,q R, S映射到7 T, U, V映射到8 W, X, Yz映射到9 Q和Z并没有相关的映射。 */ #include<iostream> using namespace std; #include<cstdio> #include<cstring> int n; int s[100]; int iv[30]={0,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,0,7,7,8,8,8,9,9,9,0}; char pp[50]; int ans[50]; int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); scanf("%d",&n); int i,j; for(i=1;i<=n;++i) { memset(ans,0,sizeof(ans)); memset(pp,0,sizeof(pp)); scanf("%s",pp+1); int t=0; int lenp=strlen(pp+1); for(j=1;j<=lenp;++j) { if(pp[j]>='A'&&pp[j]<='Z') { ++t; ans[t]=iv[pp[j]-'A'+1]; } if(pp[j]>='0'&&pp[j]<='9') { ++t; ans[t]=pp[j]-'0'; } } for(j=1;j<=t;++j) { printf("%d",ans[j]); if(j==3) { printf("-"); } } printf("\n"); } fclose(stdin); fclose(stdout); return 0; }
E:一类括号匹配问题
-
总时间限制:
- 1000ms 内存限制:
- 65536kB
-
描述
-
在程序设计中,常常使用小括号强调表达式的运算顺序,但是,左右小括号必须匹配。现给定一个不多于500个符号的表达式(串),其中可能存在多个小括号,想检查小括号的匹配问题。如果存在小括号不匹配,则输出 mismatch;如果所有小括号匹配,则按左右括号的匹配距离由小到大输出左、右括号的位置;若多个匹配的距离相等,则左括号先出现的匹配先输出;如果整个串中没有小括号,则左右位置均输出0,即 0,0; ,规定,串中第一个符号的位置为1。
匹配距离=右括号位置 - 左括号位置。
例如:
输入为: (x+y*(z-5)*(x+y))*(x+98)
输出为:
6,10
12,16
19,24
1,17
如果输入为 (x+y*(z-5))*x+y)
则不匹配,因为在最后的反括号没有相匹配的正括号。因此,输出:
mismatch
输入
- 一串符号 输出
- 按匹配距离的增序输出匹配对的左右位置,逗号间隔;如果距离相同,则按左括号出现的先后顺序输出;如果整个序列中出现不匹配现象,则输出 mismatch; 样例输入
-
(x+y*(z-5)*(x+y))*(x+98)
样例输出
6,10
12,16
19,24
1,17
代码及其分析:
/*这是一个对于数据结构--栈的考察,遇到的第一个右括号,他的左面离他最近的那个(一定和他匹配,这就是栈的思路了,对于(先都压栈,如果遇到),就把栈顶的(弹出,和他匹配,把坐标记录下就可以了*/ #include<iostream> using namespace std; #include<cstdio> #include<cstring> #include<algorithm> struct Node{ int l,r,len; bool operator<(const Node &p) const{ if(len!=p.len) return len<p.len; else return l<p.l; } }; int t=0; #define N 1001 Node node[N]; char s[N]; int list[N],top=0; int main() { scanf("%s",s+1); int lens=strlen(s+1); int i,j,k,l; bool flag=true; for(i=1;i<=lens;++i) { if(s[i]=='(') { top++;/*压栈*/ list[top]=i; } if(s[i]==')') { if(top>0)/*栈没空*/ { ++t; node[t].l=list[top];/*储存坐标*/ node[t].r=i; node[t].len=i-list[top]; top--; } else { flag=false;/*这个)没有与之匹配的*/ break; } } } if(!flag||top!=0) printf("mismatch\n"); else if(t==0)/*没有括号*/ printf("0,0\n"); else{ sort(node+1,node+t+1); for(i=1;i<=t;++i) printf("%d,%d\n",node[i].l,node[i].r); } system("pause"); return 0; }
F:棋盘问题
-
总时间限制:
- 1000ms 内存限制:
- 65536kB
-
描述
- 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。 输入
-
输入含有多组测试数据。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
输出
- 对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。 样例输入
-
2 1 #. .# 4 4 ...# ..#. .#.. #... -1 -1
样例输出
2
1
代码及其分析:
/*这个问题就是八皇后问题,不同的地方就是没有皇后的斜行攻击,但是棋盘不是均匀的,另外就是k!=n的问题,这个用循环试试每一行就行了*/ #include<iostream> using namespace std; #include<cstdio> #include<cstring> #define N 10 char p[N][N]; bool flag[N]; int jz[N][N]; int n,k; int sum=0; void dfs(int g,int i) { if(g>k)return ; if(g<k&&i==n) return ; int j,l; for(j=1;j<=n;++j) { if(jz[i][j]&&!flag[j]) flag[j]=true; else continue; if(g==k) { flag[j]=false; sum++; // return;/*这里的return必须去掉,因为这一行可能放多种情况,不能知道一个就返回*/ } for(l=i+1;l<=n;++l) dfs(g+1,l); flag[j]=false; } } void input() { sum=0; memset(flag,0,sizeof(flag)); memset(jz,0,sizeof(jz)); memset(p,0,sizeof(p)); int i,j,l; for(i=1;i<=n;++i) { char pp[N]; scanf("%s",pp+1); for(j=1;j<=n;++j) { if(pp[j]=='#') { jz[i][j]=1; } else jz[i][j]=0; } } } int main() { while(scanf("%d%d",&n,&k)==2&&n!=-1&&k!=-1) { input(); for(int i=1;i<=n;++i) dfs(1,i); printf("%d\n",sum); } return 0; }
G:多边形游戏
-
总时间限制:
- 1000ms 内存限制:
- 65536kB
-
描述
-
一个多边形,开始有n个顶点。每个顶点被赋予一个正整数值,每条边被赋予一个运算符“+”或“*”。所有边依次用整数从1到n编号。
现在来玩一个游戏,该游戏共有n步:
第1步,选择一条边,将其删除
随后n-1步,每一步都按以下方式操作:(1)选择一条边E以及由E连接着的2个顶点v1和v2; (2)用一个新的顶点取代边E以及由E连接着的2个顶点v1和v2,将顶点v1和v2的整数值通过边E上的运算得到的结果值赋给新顶点。
最后,所有边都被删除,只剩一个顶点,游戏结束。游戏得分就是所剩顶点上的整数值。那么这个整数值最大为多少?
输入
- 第一行为多边形的顶点数n(n ≤ 20),其后有n行,每行为一个整数和一个字符,整数为顶点上的正整数值,字符为该顶点到下一个顶点间连边上的运算符“+”或“*”(最后一个字符为最后一个顶点到第一个顶点间连边上的运算符)。 输出
- 输出仅一个整数,即游戏所计算出的最大值。 样例输入
-
4 4 * 5 + 5 + 3 +
样例输出
-
70
提示
小规模问题可不必用动态规划方法编程求解,仅用递归就可以求解。计算中不必考虑计算结果超出整数表达范围的问题,给出的数据能保证计算结果的有效性。
在给的例子中,计算过程为(3+4)*(5+5)=70。
代码:虽然题目中说了可以不用动态规划做,但是毕竟环形DP也是一个难点,所以我就用了环形DP做了
/*f[i][j],表示从i这个顶点,延伸k个顶点(包括它自身),所能达到的最大值, 状态的转移:通过枚举中间的断点来实现*/ #include<iostream> using namespace std; #include<cstdio> #include<cstring> #define N 45 int a[N],cha[N]; int f[N][N]; int n; void input() { scanf("%d",&n); for(int i=1;i<=n;++i) { scanf("%d",&a[i]);/*因为是环形DP,所以预处理把它延伸成为两倍的链条*/ a[n+i]=a[i]; char s[5]; scanf("%s",s+1); if(s[1]=='+') cha[n+i]=cha[i]=1;//1 表示+ else cha[n+i]=cha[i]=2;// 2表示* } } void pre_chuli() { memset(f,0,sizeof(f)); for(int i=1;i<=2*n;++i) { f[i][1]=a[i];/*预处理延长1,2的情况*/ if(cha[i]==1) f[i][2]=a[i]+a[i+1]; else f[i][2]=a[i]*a[i+1]; } } void DP() { for(int j=3;j<=n;++j) for(int i=1;i+j-1<=2*n;++i)/*注意是循环到2*才可以*/ for(int k=1;k<=j-1;++k) { if(cha[i+k-1]==2) f[i][j]=max(f[i][j],f[i][k]*(f[i+k][j-k])); else f[i][j]=max(f[i][j],f[i][k]+(f[i+k][j-k])); } } int main() { input(); pre_chuli(); DP(); int ans=-11; for(int i=1;i<=n;++i) ans=max(ans,f[i][n]); printf("%d\n",ans); return 0; }