蓝桥杯真题集2011
程序设计(满分15分)
方阵的主对角线之上称为“上三角”。
请你设计一个用于填充n阶方阵的上三角区域的程序。填充的规则是:使用1,2,3….的自然数列,从左上角开始,按照顺时针方向螺旋填充。
例如:当n=3时,输出:
1 2 3
6 4
5
当n=4时,输出:
1 2 3 4
9 10 5
8 6
7
当n=5时,输出:
1 2 3 4 5
12 13 14 6
11 15 7
10 8
9
程序运行时,要求用户输入整数n(3~20)
程序输出:方阵的上三角部分。
要求格式:每个数据宽度为4,右对齐。
思路:直接模拟下就可以了:
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<map> #include<string> #include<vector> using namespace std; const int INF=0x3f3f3f3f; #define SI(x) scanf("%d",&x) #define PI(x) printf("%d",x) #define P_ printf(" ") #define mem(x,y) memset(x,y,sizeof(x)) typedef long long LL; int mp[25][25]; int main(){ int n; SI(n); int x=1,y=0,cur=0,flot=1; while(flot){ flot=0; while(mp[x][y+1]==0&&y+1<=n)mp[x][++y]=++cur,flot=1; while(mp[x+1][y-1]==0&&x+1<=n&&y-1>0)mp[++x][--y]=++cur,flot=1; while(mp[x-1][y]==0&&x-1>0)mp[--x][y]=++cur,flot=1; } for(int i=1;i<=n;i++){ for(int j=1;j<=n-i+1;j++){ printf("%4d",mp[i][j]); } puts(""); } return 0; }
程序设计(满分16分)
公司发了某商店的购物券1000元,限定只能购买店中的m种商品。每种商品的价格分别为m1,m2,…,要求程序列出所有的正好能消费完该购物券的不同购物方法。
程序输入:
第一行是一个整数m,代表可购买的商品的种类数。
接下来是m个整数,每个1行,分别代表这m种商品的单价。
程序输出:
第一行是一个整数,表示共有多少种方案
第二行开始 ,每种方案占1行,表示对每种商品购买的数量,中间用空格分隔。
例如:
输入:
2
200
300
则应输出:
2
2 2
5 0
输入:
2
500
800
则应输出:
1
2 0
思路:暴力一下,然后判下重就好了,看了答案上面的不需要判重就可以。写的很好:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<map> #include<string> #include<vector> using namespace std; const int INF=0x3f3f3f3f; #define SI(x) scanf("%d",&x) #define PI(x) printf("%d",x) #define P_ printf(" ") #define mem(x,y) memset(x,y,sizeof(x)) typedef long long LL; int dp[1010]; int ans[1010][1010]; int th[1010]; int m,nu; void dfs(int bg){ if(bg<0)return; if(bg==0){ int flot=1; for(int j=0;j<nu;j++){ int temp=0; for(int i=0;i<m;i++)if(dp[i]!=ans[j][i])temp=1; if(!temp)flot=0; } //printf("%d\n",nu); if(!flot)return; for(int i=0;i<m;i++)ans[nu][i]=dp[i]; nu++; return; } for(int i=0;i<m;i++){ dp[i]++; dfs(bg-th[i]); dp[i]--; } } int main(){ SI(m); for(int i=0;i<m;i++)SI(th[i]); mem(dp,0); mem(ans,0); nu=0; dfs(1000); printf("%d\n",nu); for(int i=nu-1;i>=0;i--){ for(int j=0;j<m;j++){ if(j)P_; PI(ans[i][j]); } puts(""); } return 0; }
答案上的:
#include <stdio.h> int sln;//方案的个数 int gm;//商品的种类 int price[1000];//各种商品价钱 int count[1000];//各种商品的个数 int method[1000][1000];//每种解决方案中各商品的个数 int cost;//当前花费 void output()//输出解决方案 { int i,j; printf("%d\n",sln); for (i=0; i<sln; i++) { for (j=0;j<gm;j++) printf("%3d",method[i][j]); printf("\n"); } } void fun(int m) { int i; if (cost == 1000) { for (i=0; i<gm ; i++) method[sln][i] = count[i]; sln++; return; } if (cost>1000 || m<0) return; //choose m ++count[m]; cost += price[m]; fun(m); //not choose m --count[m]; cost -= price[m]; fun(m-1); } void main() { int m;//商品的种类 int k; scanf("%d",&m); gm=m; for (k=0;k<m;k++) scanf("%d",&price[k]); fun(m-1); output(); }
程序设计(满分28分)
一种Playfair密码变种加密方法如下:首先选择一个密钥单词(称为pair)(字母不重复,且都为小写字母),然后与字母表中其他字母一起填入至一个5x5的方阵中,填入方法如下:
1.首先按行填入密钥串。
2.紧接其后,按字母序按行填入不在密钥串中的字母。
3.由于方阵中只有25个位置,最后剩下的那个字母则不需变换。
如果密钥为youandme,则该方阵如下:
y o u a n
d m e b c
f g h i j
k l p q r
s t v w x
在加密一对字母时,如am,在方阵中找到以这两个字母为顶点的矩形(红色字体):
y o u a n
d m e b c
f g h i j
k l p q r
S t v w x
这对字母的加密字母为该矩形的另一对顶点,如本例中为ob。
请设计程序,使用上述方法对输入串进行加密,并输出加密后的串。
另外有如下规定:
1、一对一对取字母,如果最后只剩下一个字母,则不变换,直接放入加密串中;
2、如果一对字母中的两个字母相同,则不变换,直接放入加密串中;
3、如果一对字母中有一个字母不在正方形中,则不变换,直接放入加密串中;
4、如果字母对出现在方阵中的同一行或同一列,如df或hi,则只需简单对调这两个字母,即变换为fd或ih;
5、如果在正方形中能够找到以字母对为顶点的矩形,假如字母对为am,则该矩形的另一对顶点字母中,与a同行的字母应在前面,在上例中应是ob;同样若待变换的字母对为ta,则变换后的字母对应为wo;
6、本程序中输入串均为小写字母,并不含标点、空格或其它字符。
解密方法与加密相同,即对加密后的字符串再加密,将得到原始串。
要求输入形式如下:
从控制台输入两行字符串,第一行为密钥单词(长度小于等于25),第二行为待加密字符串(长度小于等于50),两行字符串末尾都有一个回车换行符,并且两行字符串均为小写字母,不含其它字符。
在标准输出上输出加密后的字符串。
例如,若输入:
youandme
welcometohangzhou
则表示输入的密钥单词为youandme,形成的正方形如上所示;待加密字符串为welcometohangzhou。在正方形中可以找到以第一对字母we为顶点的矩形,对应另一对顶点字母为vb,因此加密后为vb,同理可找到与字母对lc,et,oh,ho对应的顶点字母对。而字母对om位于上述正方形中的同一列,所以直接以颠倒这两个字母来加密,即为mo,字母对an同理。字母对gz中的z不在上述正方形中,因此原样放到加密串中。最后剩一个字母u也原样输出。
因此输出的结果为:
Vbrmmomvugnagzguu
思路: 也就是根据题意写,稍微有点麻烦,先把mp就出来,然后根据加密串按规则进行编码;
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<map> 7 #include<string> 8 #include<vector> 9 using namespace std; 10 const int INF=0x3f3f3f3f; 11 #define SI(x) scanf("%d",&x) 12 #define PI(x) printf("%d",x) 13 #define P_ printf(" ") 14 #define mem(x,y) memset(x,y,sizeof(x)) 15 typedef long long LL; 16 char mp[6][6]; 17 int vis[30]; 18 char s[30]; 19 struct Dot{ 20 int x,y; 21 Dot(int x=0,int y=0):x(x),y(y){} 22 }; 23 void mdmp(){ 24 int len=strlen(s); 25 int cur=0,pos=0; 26 mem(vis,0); 27 for(int i=1;i<=5;i++){ 28 for(int j=1;j<=5;j++){ 29 if(cur<len)vis[s[cur]-'a']=1,mp[i][j]=s[cur++]; 30 else{ 31 while(vis[pos])pos++; 32 vis[pos]=1; 33 mp[i][j]=pos+'a'; 34 } 35 } 36 } 37 } 38 void work(int pos,char a,char b){ 39 Dot x,y; 40 if(a==b){ 41 if(pos==0)a='A'+(a-'a'); 42 printf("%c",a); 43 printf("%c",b); 44 return; 45 } 46 for(int i=1;i<=5;i++){ 47 for(int j=1;j<=5;j++){ 48 if(mp[i][j]==a)x=Dot(i,j); 49 if(mp[i][j]==b)y=Dot(i,j); 50 } 51 } 52 if(x.x==0||y.x==0){ 53 if(pos==0)a='A'+(a-'a'); 54 printf("%c",a); 55 printf("%c",b); 56 return; 57 } 58 if(x.x==y.x||x.y==y.y){ 59 if(pos==0)b='A'+(b-'a'); 60 printf("%c",b); 61 printf("%c",a); 62 return; 63 } 64 char tmp=mp[x.x][y.y]; 65 if(pos==0)tmp='A'+(mp[x.x][y.y]-'a'); 66 printf("%c",tmp); 67 printf("%c",mp[y.x][x.y]); 68 } 69 int main(){ 70 char dai[60]; 71 scanf("%s",s); 72 scanf("%s",dai); 73 mdmp(); 74 int len=strlen(dai); 75 for(int i=0;i<=len-2;i+=2){ 76 work(i,dai[i],dai[i+1]); 77 } 78 if(len==1)printf("%c\n",'A'+dai[len-1]-'a'); 79 else if(len&1)printf("%c\n",dai[len-1]); 80 return 0; 81 }