蓝桥杯第二届决赛B组

本文介绍了蓝桥杯编程竞赛中的几道题目,涉及数论、位运算、最小公倍数计算、地铁线路换乘策略优化和二值图像连通区域分析。题目要求填写代码实现相应功能,并遵循ANSI C标准,不使用特定库或硬件相关API。
摘要由CSDN通过智能技术生成

**

1

**
数论中有著名的四方定理:所有自然数至多只要用四个数的平方和就可以表示。
我们可以通过计算机验证其在有限范围的正确性。

对于大数,简单的循环嵌套是不适宜的。下面的代码给出了一种分解方案。

请仔细阅读,填写空缺的代码(下划线部分)。

注意:请把填空的答案(仅填空处的答案,不包括题面)存入考生文件夹下对应题号的“解答.txt”中即可。
直接写在题面中不能得分。

int f(int n, int a[], int idx)
{
	if(______________) return 1;  // 填空1
	if(idx==4)  return 0;

	for(int i=(int)sqrt(n); i>=1; i--)
	{
		a[idx] = i;

		if(_______________________)  return 1;  // 填空2
	}

	return 0;
}

int main(int argc, char* argv[])
{
	for(;;)
	{
		int number;
		printf("输入整数(1~10亿):");
		scanf("%d",&number);
		
		int a[] = {0,0,0,0};

		int r = f(number, a, 0);

		printf("%d: %d %d %d %d\n", r, a[0], a[1], a[2], a[3]);
		
	}

	return 0;
}

a[0]*a[0] + a[1]*a[1] + a[2]*a[2] + a[3]*a[3] == n
f(n, a, idx + 1) == 1

**

2

**

在对文本进行简单加密的时候,可以选择用一个n位的二进制数,对原文进行异或运算。
解密的方法就是再执行一次同样的操作。

加密过程中n位二进制数会循环使用。并且其长度也可能不是8的整数倍。

下面的代码演示了如何实现该功能。
请仔细阅读,填写空缺的代码(下划线部分)。

void f(char* buf, unsigned char* uckey, int n)
{

	int i;
	for(i=0; i<n; i++)
		buf[i] = buf[i] ^ uckey[i];    //异或运算,即:buf[i] ^= uckey[i]
}

int main(int argc, char* argv[])
{
	char p[] = "abcd中国人123";  // 待加密串

	char* key = "11001100010001110";  //以串的形式表达的密匙,运算时要转换为按位存储的形式。

	int np = strlen(p);
	int nk = strlen(key);
	unsigned char* uckey = (unsigned char*)malloc(np);  
	// unsigned char是无符号字节型,char类型变量的大小通常为1个字节(1字节=8个位)	
	// 密匙串需要按位的形式循环拼入 uckey中
	int i;
	for(i=0; i<np*8; i++)
	{
		if(key[i%nk]=='1')
			______;  // 填空1按位或
		else
			______;  // 填空2按位与
	}
	
	f(p, uckey, strlen(p));
	f(p, uckey, strlen(p));

	printf("%s\n", p);

	free(uckey);

	return 0;
}

uckey[i/8] |= (unsigned char)0x80 >> (i%8)
uckey[i/8] &= ~((unsigned char)0x80 >> (i%8))

>>表示右移位,位逻辑运算符:&按位与,|按位或,^按位异或,~取反,移位运算符:<<左移,>>右移
从数学上看,左移1位等于乘以2,右移1位等于除以2,然后再取整,移位溢出的丢弃
整型常量
整型常量有3种表示方式:
①十进制整数。例如,123、一456、0。
②八进制整数。以0开头的整数是八进制数。例如,0123表示8进制数123<8),等于十进制数83。
③十六进制整数。以ox或0x开头的整数是十六进制数。例如,0x1.23或0Xl 23表示十六进制数123…),等于十进制数291。
如果在整型常量后面加上字母u或u,则表示无符号整数(unsigned int)。例如,123U或123u是unsigned int型的。如果在整型常量后面加上一个字母L或l,则表示长整数(10ngint)。例如,123[.或123l是long int型的。

这题我看了很久,终于理解它深邃的思想了。
if(key[i%nk]==‘1’) //就是循环取key

uckey[i/8] |= (unsigned char)0x80 >> (i%8)
每次取1个二进制数每8个组成一个字符;0x80=1000 0000,i%8表示当前取得数是8位中的第几个数
当i0时,uckey[i/8] |= (unsigned char)0x80 >> (i%8) --》0000 0000|= 1000 0000>>0 --》1000 0000
当i
1时,uckey[i/8] |= (unsigned char)0x80 >> (i%8) --》1000 0000|= 1000 0000>>1 --》1100 0000
当i==2时,uckey[i/8] &= ~((unsigned char)0x80 >> (i%8)) --》1100 0000&= ~(1000 0000>&g

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值