听说过这种游戏吗?游戏者按规则在特殊棋盘跳动,将跳过的数字用加或减连起来,使得尽量接近零。
棋盘如图,大小是中间行的方块数N(图中N = 4)。游戏者从底下开始,如图示方向到达最顶端,过程中不得跳出棋盘。最后把2N-1个数依次写下,在其中插入“+”或“-”,使结果接近零。
如图为例,我们可以计算如下路径: 7+8+(-5)+(-2)-5-1-2=0, 7+10+(-7)-6+(-3)-3+2=0, 7+10+(-5)-10-5+1+2=0, or 7+10+(-5)+(-2)-5-3-2=0.
输入:第一行是N (1 ≤ N ≤ 30)。下面2N-1行给出棋盘中方块的数字。第(i+1)行的第j个数对应棋盘中的 i行的第j个数(数字都在-50到50之间)。
输入有多个测试序列, N = 0结束。
输出:每个测试序列,输出得到的结果的绝对值 。
输入样例
4
2
3 1
-3 5 7
6 10 -2 20
-7 -5 -8
10 8
7
0
解题思路(1)这个问题乍一看很难。像是复杂的路径选择问题,还有正负号的选择,动态规划?状态如何转移?
注意: (数字都在-50到50之间)
我们可以记录每个方格所有可能的取值。
注意到(1 ≤ N ≤ 30),任意方格的取值不能超过1500。同时因为输出的是绝对值,所以只把非负的取值列出来就可以了。
解题思路(2)前面方格的可能取值为b1,b2,…bi
当前方格的数字为A,则当前方格的可能取值为:b1-A,b1+A,…bi-A,bi+A
核心代码及解释:bool?b[N*N][3001]; //记录所有取值
//如果b[i][j]为真,表示第i个方格可能为j
for(k=0;k<max;++k)
if(b[j][k]) //如果上一个方格可能取k
{l=ABS(k+a[i]);b[i][l]=true;
l=ABS(k-a[i]); b[i][l]=true; }
//当前方格的值可能为k-ai,k+ai.
for(i=0;i<max&&!b[t][i];++i);
printf(“%d\n”,i); //输出最小值
海明距离:描述:一个正整数A,将它写成二进制,我们叫做A的码字。
海明距离就是两个码字对应位不同个数。记为h(i,j).
例如:
i=98 j=70
i: 01100010(码字)
j: 01000110(码字)
显然第三个和第六个位置不同,所以海明距离就是2。
你的任务就是计算给定两个正整数的海明距离。
输入:输入有多个测试序列,每个一行;
每一行两个正整数i,j (0<i,j<264)。
0 0表示输入结束,并且该行不须处理。
输出: 每个测试序列,输出海明距离h(i,j) 。
输入样例
98 70
100 100
0 0
输出样例:
2
0
解题思路:
这个问题很简单,注意两个小地方:
1。数据量比较大,输入输出不要用cin/cout
推荐使用scanf/printf
在数据量比较大的时候,时间不要浪费在I/O上。
2。整数的范围是(0<i,j<264),要使用64位长整型。
__int64 unsigned i,j; //定义
Scanf(“%I64u%I64u”,&i,&j);//输入
Printf(“%I64u”,i); //输出
核心代码及解释:
__int64?unsigned?n,m; while(scanf("%I64u%I64u",&n,&m),n||m)
{
n^=m;
count=0;
while(n)
{
if(n&1)++count
;n>>=1;}
printf("%d\n",count); }