报纸页数

X星球日报和我们地球的城市早报是一样的,
都是一些单独的纸张叠在一起而已。每张纸印有4版。

比如,某张报纸包含的4页是:5,6,11,12,
可以确定它应该是最上边的第2张报纸。

我们在太空中捡到了一张X星球的报纸,4个页码分别是:
1125,1126,1727,1728

请你计算这份报纸一共多少页(也就是最大页码,并不是用了几张纸哦)?

请填写表示总页数的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

答案:2852 =(1124/2+(1728-1126)/4+1)*4


煤球数目

有一堆煤球,堆成三角棱锥形。具体:
第一层放1个,
第二层3个(排列成三角形),
第三层6个(排列成三角形),
第四层10个(排列成三角形),
....
如果一共有100层,共有多少个煤球?

请填表示煤球总数目的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

答案:171700(打表,注意是总数不是第100层的)


平方怪圈

如果把一个正整数的每一位都平方后再求和,得到一个新的正整数。
对新产生的正整数再做同样的处理。

如此一来,你会发现,不管开始取的是什么数字,
最终如果不是落入1,就是落入同一个循环圈。

请写出这个循环圈中最大的那个数字。

请填写该最大数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

答案:145(笔算一下,因为循环圈长度毕竟有限)


打印方格

小明想在控制台上输出 m x n 个方格。
比如 10x4的,输出的样子是:
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+

(如果显示有问题,可以参见【图1.jpg】)

以下是小明写的程序,请你分析其流程,填写划线部分缺少的代码。


#include <stdio.h>

//打印m列,n行的方格 
void f(int m, int n)
{
	int row;
	int col;
	
	for(row=0; row<n; row++){
		for(col=0; col<m; col++) printf("+---");
		printf("+\n");
		for(col=0; col<m; col++) printf("|   ");
		printf("|\n");		
	}
	
	printf("+");
	_____________________________;   //填空
	printf("\n");
}

int main()
{
	f(10,4);
	return 0;
}

注意:仅仅填写划线部分缺少的内容,不要添加任何已有内容或说明性文字。

答案:for(col=0; col<m; col++) printf("—+")(话说填空还能填循环语句的?)


快速排序

排序在各种场合经常被用到。
快速排序是十分常用的高效率的算法。

其思想是:先选一个“标尺”,
用它把整个队列过一遍筛子,
以保证:其左边的元素都不大于它,其右边的元素都不小于它。

这样,排序问题就被分割为两个子区间。
再分别对子区间排序就可以了。

下面的代码是一种实现,请分析并填写划线部分缺少的代码。


#include <stdio.h>

void swap(int a[], int i, int j)
{
	int t = a[i];
	a[i] = a[j];
	a[j] = t;
}

int partition(int a[], int p, int r)
{
    int i = p;
    int j = r + 1;
    int x = a[p];
    while(1){
        while(i<r && a[++i]<x);
        while(a[--j]>x);
        if(i>=j) break;
        swap(a,i,j);
    }
	______________________;
    return j;
}

void quicksort(int a[], int p, int r)
{
    if(p<r){
        int q = partition(a,p,r);
        quicksort(a,p,q-1);
        quicksort(a,q+1,r);
    }
}
    
int main()
{
	int i;
	int a[] = {5,13,6,24,2,8,19,27,6,12,1,17};
	int N = 12;
	
	quicksort(a, 0, N-1);
	
	for(i=0; i<N; i++) printf("%d ", a[i]);
	printf("\n");
	
	return 0;
}

答案:swap(a,p,j)


凑算式

     B      DEF
A + --- + ------- = 10
     C      GHI
     
(如果显示有问题,可以参见【图1.jpg】)
	 
	 
这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。

比如:
6+8/3+952/714 就是一种解法,
5+3/1+972/486 是另一种解法。

这个算式一共有多少种解法?

注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。

答案:29(搜索)


寒假作业

现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:

   □ + □ = □
   □ - □ = □
   □ × □ = □
   □ ÷ □ = □
   
   (如果显示不出来,可以参见【图1.jpg】)
   
每个方块代表1~13中的某一个数字,但不能重复。
比如:
 6  + 7 = 13
 9  - 8 = 1
 3  * 4 = 12
 10 / 2 = 5

以及: 
 7  + 6 = 13
 9  - 8 = 1
 3  * 4 = 12
 10 / 2 = 5

就算两种解法。(加法,乘法交换律后算不同的方案)
 
你一共找到了多少种方案?


请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

答案:64(搜索+剪枝)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;
int res[12],ans;
bool vis[14];

bool check() {
	if (res[11] * res[10] == res[9]) {
		return true;
	}
	return false;
}

void DFS(int idx) {
	if (idx == 12) {
		if (check()) {
			printf("\n%d + %d = %d\n",res[0],res[1], res[2]);
			printf("%d - %d = %d\n",res[3],res[4],res[5]);
			printf("%d * %d = %d\n",res[6],res[7],res[8]);
			printf("%d / %d = %d\n",res[9],res[10],res[11]);
			ans++;
		}
		return ;
	}
	if (idx == 2) {
		if (res[0] + res[1] > 13 || vis[res[0] + res[1]] == true) {
			return ;
		}
		res[2] = res[0] + res[1];
		vis[res[2]] = true;
		DFS(idx+1);
		vis[res[2]] = false;
		return ;
	}
	if (idx == 5) {
		if (res[3] - res[4] < 1 || vis[res[3] - res[4]] == true) {
			return ;
		}
		res[5] = res[3] - res[4];
		vis[res[5]] = true;
		DFS(idx+1);
		vis[res[5]] = false;
		return ;
	}
	if (idx == 8) {
		if (res[6] * res[7] > 13 || vis[res[6] * res[7]] == true) {
			return ;
		}
		res[8] = res[6] * res[7];
		vis[res[8]] = true;
		DFS(idx+1);
		vis[res[8]] = false;
		return ;
	}
	for (int i = 1; i < 14; i++) {
		if (!vis[i]) {
			vis[i] = true;
			res[idx] = i;
			DFS(idx+1);
			vis[i] = false;
		}
	}
}

int main() {
	memset(vis, false, sizeof(vis));
	ans = 0;
	DFS(0);
	printf("%d", ans);
	return 0;
}

冰雹数

任意给定一个正整数N,
如果是偶数,执行: N / 2
如果是奇数,执行: N * 3 + 1

生成的新的数字再执行同样的动作,循环往复。

通过观察发现,这个数字会一会儿上升到很高,
一会儿又降落下来。
就这样起起落落的,但最终必会落到“1”
这有点像小冰雹粒子在冰雹云中翻滚增长的样子。

比如N=9
9,28,14,7,22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1
可以看到,N=9的时候,这个“小冰雹”最高冲到了52这个高度。

输入格式:
一个正整数N(N<1000000)
输出格式:
一个正整数,表示不大于N的数字,经过冰雹数变换过程中,最高冲到了多少。

例如,输入:
10
程序应该输出:
52

再例如,输入:
100
程序应该输出:
9232

资源约定:
峰值内存消耗 < 256M
CPU消耗  < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。

模拟,题目的意思是找N以内包括N所有的数能到达的最高点而不是只有N(阅读理解…)

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;

LL mmax,N,tmp;

int main() {
	cin >> N;
	mmax = 1;
	for (int i = 1; i <= N; i++) {
		tmp = i;
		do {
			if (tmp & 1) {
				tmp = tmp * 3 + 1;
				mmax = max(mmax, tmp);
			}else {
				tmp /= 2;
			}
		}while (tmp != 1);
	}
	cout << mmax << endl;
	return 0;
}

卡片换位

你玩过华容道的游戏吗?
这是个类似的,但更简单的游戏。
看下面 3 x 2 的格子

+---+---+---+
| A | * | * |
+---+---+---+
| B |   | * |
+---+---+---+

在其中放5张牌,其中A代表关羽,B代表张飞,* 代表士兵。
还有一个格子是空着的。

你可以把一张牌移动到相邻的空格中去(对角不算相邻)。
游戏的目标是:关羽和张飞交换位置,其它的牌随便在哪里都可以。

输入格式:
输入两行6个字符表示当前的局面

输出格式:
一个整数,表示最少多少步,才能把AB换位(其它牌位置随意)

例如,输入:
* A
**B

程序应该输出:
17

再例如,输入:
A B
***

程序应该输出:
12


资源约定:
峰值内存消耗 < 256M
CPU消耗  < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。

思路1是:地图压缩在一个12位四进制的数中 0表示该处为空 1表示该处为士兵 2表示该处为张飞,然后状压bfs,不过不会四进制的数的快速更改每个位的状态,由于图的规模不大,直接开数组模拟。

以下代码错误,待补

#include <bits/stdc++.h>

using namespace std;

int dir[4][2] = {0,1,1,0,0,-1,-1,0};

struct Node {
	char mp[2][3];
	int step;
	int x,y;

	Node() {}

	Node (char mp[][3]) {
		for (int i = 0; i < 2; i++) {
			for (int j = 0; j < 3; j++) {
				(this->mp)[i][j] = mp[i][j];
				if (mp[i][j] == ' ') {
					x = i;
					y = j;
				}
			}
		}
		step = 0;
	}
	
	Node operator = (const Node& B) {
		step = B.step;
		x = B.x;
		y = B.y;
		for (int i = 0; i < 2; i++) {
			for (int j = 0; j < 3; j++) {
				mp[i][j] = (B.mp)[i][j];
			}
		}
		return (*this);
	}
	
	~Node(){}
};

queue<Node> Q;
pair<int, int > A,B;
char mp[2][3];
bool vis[4][4][4][4][4][4];

bool check (Node& ans) {
	if (ans.mp[A.first][A.second] == 'B' && ans.mp[B.first][B.second] == 'A') {
		return true;
	}
	return false;
}

int hash_func (char ch) {
	int idx = 0;
	switch(ch) {
	case '*':
		idx = 0;
		break;
	case ' ':
		idx = 1;
		break;
	case 'A':
		idx = 2;
		break;
	case 'B':
		idx = 3;
		break;
	}
	return idx;
}

int BFS () {
	int i,nx,ny;
	Node now(mp),nxt;
	while (!Q.empty()) {
		Q.pop();
	}
	Q.push(now);
	while (!Q.empty()) {
		now = Q.front();
		Q.pop();
		if (check(now)) {
			return now.step;
		}
		for (i = 0; i < 4; i++) {
			nxt = now;
			nx = nxt.x + dir[i][0];
			ny = nxt.y + dir[i][1];
			if (nx < 0 || nx > 1 || ny < 0 || ny > 2) {
				continue;
			}
			(nxt.mp)[nxt.x][nxt.y] = nxt.mp[nx][ny];
			(nxt.mp)[nx][ny] = ' ';
			nxt.x = nx;
			nxt.y = ny;
/* printf("\n=============\n"); printf("x = %d y = %d\n",nx,ny); for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { putchar((nxt.mp)[i][j]); } putchar('\n'); } printf("\n=============\n"); */
			nxt.step++;
			if (check(nxt)) {
				return nxt.step;
			}
			if (!vis[hash_func(nxt.mp[0][0])][hash_func(nxt.mp[0][1])][hash_func(nxt.mp[0][2])][hash_func(nxt.mp[1][0])][hash_func(nxt.mp[1][1])][hash_func(nxt.mp[1][2])]) {
				Q.push(nxt);
				vis[hash_func(nxt.mp[0][0])][hash_func(nxt.mp[0][1])][hash_func(nxt.mp[0][2])][hash_func(nxt.mp[1][0])][hash_func(nxt.mp[1][1])][hash_func(nxt.mp[1][2])] = true;
			}
		}
	}
	return 0;
}

int main() {
	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 3; j++) {
			mp[i][j] = getchar();
			if (mp[i][j] == 'A') {
				A.first = i;
				A.second = j;
			} else if (mp[i][j] == 'B') {
				B.first = i;
				B.second = j;
			}
		}
		getchar();
	}
	/* for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { putchar(mp[i][j]); } putchar('\n'); }*/
	memset(vis, false, sizeof(vis));
	cout << BFS() << endl;
	return 0;
}

密码脱落

X星球的考古学家发现了一批古代留下来的密码。
这些密码是由A、B、C、D 四种植物的种子串成的序列。
仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串)。
由于年代久远,其中许多种子脱落了,因而可能会失去镜像的特征。

你的任务是:
给定一个现在看到的密码串,计算一下从当初的状态,它要至少脱落多少个种子,才可能会变成现在的样子。

输入一行,表示现在看到的密码串(长度不大于1000)
要求输出一个正整数,表示至少脱落了多少个种子。

例如,输入:
ABCBA
则程序应该输出:
0

再例如,输入:
ABDCDCBABC
则程序应该输出:
3

资源约定:
峰值内存消耗 < 256M
CPU消耗  < 3000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。

回文?我怎么看不懂样例2,qwq(待补)