题目大意
题目原文 http://uva.onlinejudge.org/external/1/102.pdf
三个箱子里面放有若干个三种颜色的瓶子,分别是B(棕色)G(绿色)和C(透明),题目要求一次移动一个瓶子最后使得三个箱子里面分别放三种不同颜色的瓶子(即最后每个箱子里面的瓶子颜色都一样),并求出最后三个箱子放的瓶子颜色,和需要移动的瓶子数。
首先要求三个箱子三个瓶子,我们可以定义一个二维数组来保存输入的数据(a[3][3]),应题目要求,输入的九个数字钟,前三个数分别是第一个箱子里面的B、G、C颜色的瓶子的个数,中间三个数是第二个箱子里面的各种颜色的瓶子数,后三个数为第三个箱子里面的各种颜色的瓶子数。而题目要求瓶子数不超过2^31,所以定义的数字是long型的。
这个题目的思路是用穷举法,由于只有三个箱子三种瓶子,所以一个一个尝试一下算出最少的移动次数即可。算法如下:
以一个循环语句来重复尝试各种情况。结果等于总瓶子数减去不需要移动的瓶子数。
另外题目还要求如果多种情况结果相等,需要按字母的顺序排列出最前面一个情况。
附上代码:

1 #include<stdio.h> 2 #include<string.h> 3 void sw(int *x,char *b)//本函数用于将x里面的数字转化成字符串保存在b中 4 { 5 int i; 6 for(i=0;i<3;i++) 7 { 8 switch(x[i]) 9 { 10 case 0:b[i]='B';break; 11 case 1:b[i]='G';break; 12 case 2:b[i]='C';break; 13 } 14 } 15 } 16 17 int main() 18 { 19 long a[3][3],n,max,s;//题目要求可以表示2^31内的数,s用于计算总瓶子数 20 int i,j,x[3],xi[3]; 21 char b[4]="",c[4]="";//初始化可以保证b[3]和c[3]始终是'\0' 22 while(scanf("%ld%ld%ld%ld%ld%ld%ld%ld%ld",&a[0][0],&a[0][1],&a[0][2],&a[1][0],&a[1][1],&a[1][2],&a[2][0],&a[2][1],&a[2][2])!=EOF) 23 { 24 s=0; 25 for(i=0;i<3;i++) 26 for(j=0;j<3;j++) 27 s+=a[i][j]; 28 29 max=0; 30 for(x[0]=0;x[0]<3;x[0]++) 31 for(x[1]=0;x[1]<3;x[1]++) 32 for(x[2]=0;x[2]<3;x[2]++)//三重循环加条件语句可以尝试所有情况 33 if(x[2]!=x[0]&&x[2]!=x[1]&&x[1]!=x[0])//需要互不相等 34 { 35 n=a[0][x[0]]+a[1][x[1]]+a[2][x[2]]; 36 if(max<n) 37 { 38 sw(x,b); 39 max=n; 40 xi[0]=x[0]; 41 xi[1]=x[1]; 42 xi[2]=x[2]; 43 } 44 if(max==n)//如果有相等的情况要取字符串比较小的那种情况 45 { 46 sw(x,c); 47 if(strcmp(b,c)>0) 48 { 49 strcpy(b,c); 50 max=n; 51 xi[0]=x[0]; 52 xi[1]=x[1]; 53 xi[2]=x[2]; 54 } 55 } 56 } 57 max=s-max; 58 printf("%s &ld\n",b,max); 59 } 60 return 0; 61 }