《算法竞赛入门经典》习题及反思 -<2>
数组
Master-Mind Hints,Uva 340
题目:给定答案序列和用户猜的序列,统计有多少数字对应正确(A),有多少数字在两个序列都出现过但位置不对。
输入包括多组数据。每组输入第一行为序列长度n,第二行是答案序列,接下来是若干猜测序列。猜测序列为0时改组数据结束。n=0时输入结束。
样例输入:
4
1 3 5 5
4 3 3 5
6 5 5 1
6 1 3 5
1 3 5 5
0 0 0 0
10
1 2 2 2 4 5 6 6 6 9
1 2 3 4 5 6 7 8 9 1
1 1 2 2 3 3 4 4 5 5
1 2 1 3 1 5 1 6 1 9
1 2 2 5 5 5 6 6 6 7
0 0 0 0 0 0 0 0 0 0
0
样例输出:
Game 1:
(1,1)
(2,0)
(1,2)
(1,2)
(4,0)
Game 2:
(2,4)
(3,2)
(5,0)
(7,0)
我的思路:
这里贴一段错误的代码;思路看起来是对的,但是实现和Debug过程过于麻烦,远远不及书上的思路。不必细究。
#include<stdio.h>
int main()
{
struct p
{
int a;
int b;//b stand for status used/unused
}b[105];
int n,i,j,t=0,m=0,a[105],k=0;
while(scanf("%d",&n)!=EOF && n!=0)
{
for(i=1;i<=n;i++)
b[i].b=0;//setstatus "0"
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(k=1;;k++)
{
scanf("%d",&b[1].a);
if(b[1].a==0)break;//scanf 0
else
{
for(i=2;i<=n;i++)
scanf("%d",&b[i].a);
}
for(i=1;i<=n;i++)//comparing a[i] and b[j].a
{
for(j=1;j<=n;j++)
{
if(a[i]==b[j].a && j==i)
{
t++;
if(b[j].b==1)m--;
/*for(k=1;k<=j;k++)
{
if(b[k].a==a[i] && b[k].b==1)
{
m--;
b[k].b=0;
}
}*/
b[j].b=1;
break;
}
if(a[i]==b[j].a && i!=j && b[j].b==0)
{
//if(b[j-1].b==2)break;
m++;
b[j].b=1;
break;
}
}
}
printf("Game %d: (%d,%d)\n",k,t,m);
t=0;
m=0;
for(i=1;i<=n;i++)
b[i].b=0;
}
}
return 0;
}//6 5 5 3
//1 2 2 5 5 5 6 6 6 7
这大概是我至今最失败的几次编程之一了,我定义一个结构体数组b,
b[i].a存储用户输入的数,b[i].b存储这个数的状态,如果它被调用则置1,如果被错误调用(即本来是与答案序列正确对应的,但被程序视作不对应从而使m++)置0,同时t++,m--。读者大概也能够猜出我的想法:用循环嵌套循环来寻找位置相同和不相同的数从而获取A和B的个数。
在经过几个小时的不断重复的过程中,我发现耗费在这上面的时间过多,而每一次尝试都无功而返。
不禁让我反思自己的问题,在我之前的编程中,解决问题的算法经常出现一些严重的漏洞,使我不得不去重新思考这个方法的框架,耗费的时间以小时计。别人十几分钟就可以解决的问题我会花上两三个小时。
重新思索其他的解题方法也许是一个不错的解决方法,但是我能不能找到它,并且效率是否会高,这还需我自己用时间来检验。

回到此题,可能是最简单的算法:直接统计A,为了计算B,对每个数字(0-9),统计二者出现的次数c1,c2,那么min(c1,c2)就是该数字对B的贡献。最后要减去A的部分。
代码(大体部分):
#include<stdio.h>
int main()
{
int n,i,j,c1=0,c2=0,m=0,t=0;
int a[1005],b[1005];
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(i=1;i<=n;i++)
{
scanf("%d",&b[i]);
if(b[i]==a[i])t++;//查找正确的位
}
for(i=1;i<=9;i++)//遍历1-9
{
for(j=1;j<=n;j++)
{
if(a[j]==i)c1++;//出现在a[i]中的个数
if(b[j]==i)c2++;//出现在b[i]中的个数
}
if(c1>c2)m+=c2;
else m+=c1;//m+=min(c1,c2)
c1=0;
c2=0;
}
printf("Game:(%d,%d)",t,m-t);//计算错位:m-t
return 0;
}
2016/3/9
《算法竞赛入门经典》习题及反思 -<2>的更多相关文章
- 算法竞赛入门经典 习题2-10 排列(permutation)
习题2-10 排列(permutation) 用1,2,3,-,9组成3个三位数 abc, def, 和ghi,每个数字恰好使用一次,要求 abc:def:ghi = 1:2:3.输出所有解.提示:不 ...
- 算法竞赛入门经典 习题 2-10 排列(permutation)
习题 2-10 用1,2,3.....,9组成3个三位数abc.def和ghi,每一个数字恰好使用一次,要求abc:def:ghi=1:2:3.输出全部解. #include <stdio.h& ...
- (Step1-500题)UVaOJ+算法竞赛入门经典+挑战编程+USACO
http://www.cnblogs.com/sxiszero/p/3618737.html 下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年 ...
- 算法竞赛入门经典+挑战编程+USACO
下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年到1年半年时间完成.打牢基础,厚积薄发. 一.UVaOJ http://uva.onlinej ...
- [刷题]算法竞赛入门经典 3-12/UVa11809
书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 题目:算法竞赛入门经典 3-4/UVa11809:Floating-Point Numbers 代码: //UVa11 ...
- [刷题]算法竞赛入门经典 3-10/UVa1587 3-11/UVa1588
书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 题目:算法竞赛入门经典 3-10/UVa1587:Box 代码: //UVa1587 - Box #include&l ...
- [刷题]算法竞赛入门经典 3-7/UVa1368 3-8/UVa202 3-9/UVa10340
书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 都是<算法竞赛入门经典(第二版)>的题目,标题上没写(第二版) 题目:算法竞赛入门经典 3-7/UVa13 ...
- [刷题]算法竞赛入门经典 3-4/UVa455 3-5/UVa227 3-6/UVa232
书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 题目:算法竞赛入门经典 3-4/UVa455:Periodic Strings 代码: //UVa455 #inclu ...
- [刷题]算法竞赛入门经典 3-1/UVa1585 3-2/UVa1586 3-3/UVa1225
书上具体所有题目:http://pan.baidu.com/s/1hssH0KO(我也是在网上找到的pdf,但不记得是从哪里搜刮到的了,就重新上传了一遍) PS:第一次写博客分享我的代码,不知道我对c ...
- 算法竞赛入门经典训练指南——UVA 11300 preading the Wealth
A Communist regime is trying to redistribute wealth in a village. They have have decided to sit ever ...
随机推荐
- [LeetCode] 221. Maximal Square _ Medium Tag: Dynamic Programming
Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and re ...
- javascript unicode与GBK2312(中文)编码转换示例
一个javascript的unicode与GBK2312编码相互转换的方法. 代码: var GB2312UnicodeConverter = { ToUnicode: function (s ...
- c/c++的预处理定义 Stringizing Operator (#) Charizing Operator (#@) Token-Pasting Operator (##)
c/c++的预处理定义:一.Stringizing Operator (#)在c和c++中数字标志符#被赋予了新的意义,即字符串化操作符.其作用是:将宏定义中的传入参数名转换成用一对双引号括起来参数名 ...
- Firefox及我使用的firefox扩展
什么数字安全浏览器,什么极速浏览器,现在都取代不了Firefox在我心中的位置.你想想,一款浏览器老是弹呀弹的,时不时问我换不换桌面,问我请不清理垃圾,真是的,这些关它浏览器鸟事. 喜欢Firefox ...
- MFC六大核心机制之三:动态创建
MFC中很多地方都使用了动态创建技术.动态创建就是在程序运行时创建指定类的对象.例如MFC的单文档程序中,文档模板类的对象就动态创建了框架窗口对象.文档对象和视图对象.动态创建技术对于希望了解MFC底 ...
- yii2之增加省市字段
第一步,利用数据库迁移文件改表 修改一下迁移文件: https://bitbucket.org/ysxy/zijiu.git
- Linux基础命令---cmp
cmp 用字节的方式,比较两个文件是否存在差异,但是不保存运算结果.Cmp指令只会根据结果设置相关的标志位,这个指令之后往往会跟着一个条件跳转指令. 此命令的适用范围:RedHat.RHEL.Ubun ...
- Linux基础命令---mke2fs
mke2fs 在磁盘分区上创建ext2.ext3.ext4文件系统,默认情况下会创建ext2.此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fedo ...
- clock_gettime接口和linux时间系统
RTC/OSCRTC,Real Time Clock,真实时钟,也叫做CMOS时钟,又叫walltimeOSC,Operation System Clock,系统时钟.在开机时操作系统取得RTC中的时 ...
- JavaScript计算星期几
function zeller(dateStr) { var c = parseInt(dateStr.substr(0, 2)); var y = parseInt(dateStr.substr(2 ...