题目
1.计数器
**********************************************************************源程序名: count.???(C,CPP) *
*可执行文件名: count.exe *
*输入文件名: count.in *
*输出文件名: count.out *
*********************************************************************
【问题描述】
一本书的页数为N,页码从1开始编起,请你求出全部页码中,用了多少个0,1,2,3,……,9,其中一个页码不含多余的0,如N = 1234时第5页不是0005,只是5。
【输入】
一个正整数N(1<=N<=10^9),表示总的页数。
【输出】
共十行,第K行为数字K-1的个数。
【样例】
count.in
11
count.out
1
4
1
1
1
1
1
1
1
1
代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
#define INF 1e9
#define MIN(x,y) (x<y?x:y)
long long a[10];
void count(long long n){
long long current, last, tmp = n;
int factor = 1;
int len = 0;
int i;
while(tmp){
current = n/factor%10;
last = n%factor;
for(i=0; i<=9; ++i){
a[i] += len*current*factor/10;
}
for(i=0; i<current; ++i){
a[i] += factor;
}
a[current] += last+1;
a[0] -= factor; //减去多余的0
factor *= 10;
len++;
tmp /= 10;
}
}
int main(){
long long n;
scanf("%I64d", &n);
memset(a, 0, sizeof(a));
count(n);
for(int i=0; i<10; ++i)
printf("%I64d\n", a[i]);
return 0;
}
2.排队接水
**********************************************************************源程序名: water.???(C,CPP) *
*可执行文件名: water.exe *
*输入文件名: water.in *
*输出文件名: water.out *
*********************************************************************
【问题描述】
有N个人在一个水龙头前排队接水,假如每个人接水的时间为Ti,请编程找出这N个人排队的一种顺序,使得N个人的平均等待时间最小。
【输入】
输入文件一共两行,第一行为N;第二行分别表示第1个人到第N个人每人的接水时间T1,T2,……Tn,每个数据之间有一个空格。
【输出】
输出文件有两行,第一行为一种排队顺序,即1到N的一种排列(有多种最优解时输出字典序最小的序列);第二行为这种排列方案下的平均等待时间(输出结果精确到小数点后两位,四舍五入)。
【样例】
water.in
10
56 12 1 99 1000 234 33 55 99 812
water.out
3 2 7 8 1 4 9 6 10 5
291.90
代码:
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
struct Tnode{
double time;
int label;
}node[1010];
int cmp(const void *a, const void *b){
struct Tnode e1 = *(struct Tnode *)a;
struct Tnode e2 = *(struct Tnode *)b;
if(e1.time==e2.time) return e1.label - e2.label;
return e1.time - e2.time;
}
int main(){
int i, j;
int n;
scanf("%d", &n);
for(i=0; i<n; ++i){
scanf("%lf", &node[i].time);
node[i].label = i+1;
}
qsort(node, n, sizeof(struct Tnode), cmp);
double sum = 0;
for(i=0; i<n; ++i){
sum += node[i].time*(n-i-1);
printf("%d ", node[i].label);
}
printf("\n%0.2lf\n", sum/(n*1.0));
return 0;
}
3.最多因子数
**********************************************************************源程序名: divisors.???(C,CPP) *
*可执行文件名: divisors.exe *
*输入文件名: divisors.in *
*输出文件名: divisors.out *
*********************************************************************
【问题描述】
数学家门喜欢各种类型的有奇怪特性的数。例如,他们认为945是一个有趣的数,因为它是第一个所有约数之和大于本身的奇数。
为了帮助他们寻找有趣的数,你将写一个程序扫描一定范围内的数,并确定在此范围内约数个数最多的那个数。当范围很大时,我们可能会得到多个答案,此时要将他们都输出来。
【输入】
只有一行,给出扫描的范围,由下界L和上界U确定,满足2<=L<=U<=4 000。
【输出】
对于给定的范围,输出该范围内约数最多的数。若有多个,则按升序输出这些数,每个数之间用一个空格隔开。
【样例】
divisors.in
1000 2000
divisors.out
1680
代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
#define INF 1e9
#define MAX(x,y) (x>y?x:y)
#define MIN(x,y) (x<y?x:y)
#define SWAP(x,y) {(x)=(x)^(y);(y)=(x)^(y);(x)=(x)^(y);}
int data[4010];
int main(){
int i, j;
memset(data, 0, sizeof(data));
for(i=2; i<4000; ++i){
for(j=1; j<=4000; ++j){
if(j%i==0) data[j]++;
}
}
int imax;
int m, n;
scanf("%d%d", &m, &n);
imax= n;
for(i=m; i<n; ++i)
if(data[imax]<data[i]) imax = i;
bool flag = false;
for(i=m; i<=n; ++i){
if(data[imax] == data[i]){
if(flag) printf(" ");
flag = true;
printf("%d", i);
}
}
return 0;
}
4.黑白棋游戏
**********************************************************************源程序名: game.???(C,CPP) *
*可执行文件名: game.exe *
*输入文件名: game.in *
*输出文件名: game.out *
*********************************************************************
【问题描述】
黑白棋游戏的棋盘由一个4*4方格阵列构成。棋盘的每一个方格中放有1枚棋子,共有8枚白色棋子和8枚黑色棋子。这16枚棋子的每一种放置方案都构成一个游戏状态。在棋盘上拥有1条公共边的2个方格称为相邻方格。一个方格最多可有4个相邻方格。在玩黑白棋游戏时,每一步可将任何2个相邻方格中棋子互换位置。对于给定的初始游戏状态和目标游戏状态,编程计算从初始游戏状态变化到目标游戏状态的最短着棋步数。
【输入】
输入文件共有8行。前四行是初始游戏状态,后四行目标游戏状态。每行4个数分别表示该行放置的棋子颜色。“0”表示白棋;“1”表示黑棋。
【输出】
输出文件是最少着棋步数N。
【样例】
game.in
1 1 1 1
0 0 0 0
1 1 1 0
0 0 1 0
1 0 1 0
0 1 0 1
1 0 1 0
0 1 0 1
game.out
4
代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
#define INF 1e9
#define MIN(x,y) (x<y?x:y)
#define SWAP(x,y) {(x)=(x)^(y);(y)=(x)^(y);(x)=(x)^(y);}
bool visit[16][16][16][16];
int end[4];
int start[4];
int queue[16*16*16*16][5];
void swap_row(int &m, int &n, int pos){
int first[4], second[4];
for(int i=0; i<4; ++i){
first[4-i-1] = m%2;
m /= 2;
}
for(int i=0; i<4; ++i){
second[4-i-1] = n%2;
n /= 2;
}
swap(first[pos], second[pos]);
for(int i=0; i<4; ++i)
m = m*2 + first[i];
for(int i=0; i<4; ++i)
n = n*2 + second[i];
}
void swap_col(int &m, int pos){
int first[4];
for(int i=0; i<4; ++i){
first[3-i] = m%2;
m /= 2;
}
SWAP(first[pos], first[pos+1]);
for(int i=0; i<4; ++i)
m = m*2 + first[i];
}
bool judge(int m){
for(int i=0; i<4; ++i)
if(queue[m][i] != end[i]){
return false;
}
return true;
}
void print(int now){
static int key = 1;
printf("Key:%d Start..\n", key);
key++;
int first[4][4];
int i, j, tmp;
for(i=0; i<4; i++){
tmp = queue[now][i];
for(j=0; j<4; j++){
first[i][3-j] = tmp%2;
tmp /= 2;
}
}
for(i=0; i<4; i++){
for(j=0; j<4; ++j){
printf("%d ", first[i][j]);
}
printf("\n");
}
printf("END....\n\n");
}
int main(){
int i, j;
memset(start, 0, sizeof(start));
memset(end, 0, sizeof(end));
memset(visit, false, sizeof(visit));
int s[4][4];
int e[4][4];
for(i=0; i<4; ++i){
for(j=0; j<4; ++j){
scanf("%d", &s[i][j]);
start[i] = start[i]*2+s[i][j];
}
// printf("%d\n", start[i]);
}
for(i=0; i<4; ++i){
for(j=0; j<4; ++j){
scanf("%d", &e[i][j]);
end[i] = end[i]*2 + e[i][j];
}
// printf("%d\n", end[i]);
}
visit[start[0]][start[1]][start[2]][start[3]] = true;
for(i=0; i<4; ++i)
queue[0][i] = start[i];
queue[0][4] = 0;
int head =0, tail = 1;
// print(head);
// printf("HELLO \n\n\n");
while(tail>head){
if(judge(head)){
printf("%d\n", queue[head][4]);
break;
}
for(i=0; i<3; ++i){
for(j=0; j<4; ++j){
swap_row(queue[head][i], queue[head][i+1], j);
if(!visit[queue[head][0]][queue[head][1]][queue[head][2]][queue[head][3]]){
visit[queue[head][0]][queue[head][1]][queue[head][2]][queue[head][3]] = true;
for(int k=0; k<4; ++k)
queue[tail][k] = queue[head][k];
queue[tail][4] = queue[head][4]+1;
// print(tail);
//getchar();
tail++;
}
swap_row(queue[head][i], queue[head][i+1], j);
}
}
for(i=0; i<4; ++i){
for(j=0; j<3; ++j){
swap_col(queue[head][i], j);
if(!visit[queue[head][0]][queue[head][1]][queue[head][2]][queue[head][3]]){
visit[queue[head][0]][queue[head][1]][queue[head][2]][queue[head][3]] = true;
for(int k=0; k<4; ++k)
queue[tail][k] = queue[head][k];
queue[tail][4] = queue[head][4]+1;
tail++;
}
swap_col(queue[head][i], j);
}
}
head++;
}
//printf("%d", queue[head][4]);
return 0;
}