A. 结果填空:年龄问题
某君的年龄是个两位数,如果把他年龄的两位数字交换位置后与原数字相加和为 x,与原数字相减差的绝对值为 y。已知 x 比 y 大 32。请你计算 y 的值是多少
思路:枚举
结果:45
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
int main() {
for(int i=10;i<=99;++i) {
int g=i%10;
int s=i/10;
int j=g*10+s;
if(abs(i+j)-abs(i-j)==32) {
printf("%d\n",abs(i-j));
break;
}
}
return 0;
}
B. 结果填空:方程的解
给出方程组:
11x+13y+17z=2471
13x+17y+11z=2739
已知 x,y,z 均为正整数,请你计算 x,y,z相加和最小为多少
思路:枚举结果:181
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
int main() {
int minres=3000;
for(int i=1;i<=2471/11;++i)
for(int j=1;j<=2471/13;++j)
for(int k=1;k<=2471/17;++k)
if(((i*11+j*13+k*17)==2471)&&(13*i+17*j+11*k)==2739)
minres=min(minres,i+j+k);
printf("%d\n",minres);
return 0;
}
C. 结果填空:九宫格
将数字 1…9 填入一个3×3 的九宫格中,使得格子中每一横行和的值全部相等,每一竖列和的值全部相等。请你计算有多少种填数字的方案。
思路:全排列
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<string>
using namespace std;
int main() {
int ans[9],sum=0;
for(int i=0;i<9;++i) ans[i]=i+1;
do {
int temp1=ans[0]+ans[1]+ans[2];
int temp2=ans[0]+ans[3]+ans[6];
if(((ans[3]+ans[4]+ans[5])==temp1)
&&((ans[6]+ans[7]+ans[8])==temp1)
&&((ans[1]+ans[4]+ans[7])==temp2)
&&((ans[2]+ans[5]+ans[8])==temp2))
sum++;
}while(next_permutation(ans,ans+9));
printf("%d\n",sum);
return 0;
}
D. 代码填空:阶梯三角形
我们给出三角形的高度,通过函数在控制台上打印出一个三角形。右侧代码连续打印了几个大小不同三角形,最后形成了一个阶梯状的连续三角形。
请仔细阅读代码,填写缺失代码,完成图形的打印。
代码:
#include<stdio.h>
void print(int n) {
for (int i = 0; i < n - 1; ++i) {
for (int j = 0; j <= n + i - 1; ++j) {
if (j+i==n-1) {
printf("*");
} else if (j == n + i - 1) {
printf("*");
} else {
printf(" ");
}
}
printf("\n");
}
for (int i = 0; i < n * 2 - 1; ++i) {
printf("*");
}
printf("\n");
}
int main() {
for (int i = 1; i <= 16; i *= 2) {
print(i);
}
return 0;
}
E. 代码填空:组合数字
右侧代码是将 6 个整数按照任意顺序组合到一起,计算能组合出的最大数字。
例如:4123,25,66 组合到一起就是 66412325。
请阅读程序补全代码,实现这个功能
#include<stdio.h>
long long max(long long x, long long y) {
return x > y ? x : y;
}
long long test(int a[], int n) {
long long ret = 0;
for (int i = 0; i < n; ++i) {
int tp = a[i];
int j = 1;
while(tp) {
j *= 10;
tp /= 10;
}
ret = ret * j + a[i];
}
return ret;
}
long long f(int a[], int k) {
if (k == 6) {
return test(a, k);
}
long long ret = 0;
for(int i = k; i < 6; ++i) {
int t = a[k];
a[k] = a[i];
a[i] = t;
ret = max(ret,f(a,k+1));
t = a[k];
a[k] = a[i];
a[i] = t;
}
return ret;
}
int main() {
int a[6] = {517, 283, 429, 65, 6566, 32};
printf("%lld\n", f(a, 0));
return 0;
}
F. 结果填空:补全等式
下图中,每个方块代表 1…13 中的某一个数字,但不重复。
例如:
1×2+9×7=13×5
10×8+12×3=11×4
只要有任意一个方块代表的数字不同,就算两种不同的方案。
请你计算,一共有多少种不同的方案。
结果:122368 运行时长:300.010s思路:DFS 运行时长比较长
代码:
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
int ans[13];
bool flag[14];
int sum=0;
void cal() {
int temp1=ans[1]*ans[2]+ans[3]*ans[4];
int temp2=ans[5]*ans[6];
int temp3=ans[7]*ans[8]-ans[9]*ans[10];
int temp4=ans[11]*ans[12];
if((temp1==temp2)&&(temp3==temp4)) {
sum++;
printf("%d\n",sum);
}
}
void dfs(int pos) {
if(pos==13) {
cal();
return;
}
for(int i=1;i<=13;++i) {
if(flag[i]==true) continue;
flag[i]=true;
ans[pos]=i;
dfs(pos+1);
flag[i]=false;
}
}
int main() {
memset(ans,0,sizeof(ans));
memset(flag,false,sizeof(flag));
dfs(1);
printf("%d\n",sum);
return 0;
}
G. 结果填空:礼物盒
小y有一个宽度为 100cm,高度为 20cm,深度为 1cm的柜子,如下图。
小y还有 3636 个礼物盒,他们的深度都为 1cm。
他们对应的宽度和高度如下,单位(cm)。
现在小y想把这些盒子放到柜子上,由于礼物盒里面都装有礼物,礼物盒必须向上放置,并且不能堆放。由于礼物盒深度和柜子深度一样,所以礼物盒和柜子深度方向也必须一致。并且礼物盒的高度还不能大于柜子的高度,否者放不进去。小y希望放到柜子上礼物盒的宽度和正好等于柜子的宽度,也就是希望柜子两边都不存在间隙。如下图符合条件的放置。
满足条件的情况下,小y希望能尽可能多的放置礼物盒,算出最多能放多少个礼物盒。
思路:放满的01背包
结果:18
代码:
/*
11 3
8 12
11 17
16 13
1 14
2 8
6 10
10 18
17 11
10 15
6 14
5 6
2 19
19 10
4 9
7 9
5 14
5 20
15 19
3 17
15 11
7 25
11 20
9 12
17 4
9 19
4 18
10 10
12 19
17 3
19 9
20 16
11 16
10 2
20 15
3 14
*/
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstring>
using namespace std;
const int INF=-0x3f3f3f3f;
int main() {
int t=36,h,w;
vector<int> ans;
while(t--) {
scanf("%d%d",&w,&h);
if(h>20) continue;
ans.push_back(w);
}
int n=ans.size();
ans.push_back(*ans.end());
for(int i=n-1;i>=1;--i) ans[i]=ans[i-1];
int dp[n+1][101];
memset(dp,INF,sizeof(dp));
for(int i=0;i<=n;i++) {
dp[i][0]=0;dp[0][i]=0;
}
for(int i=1;i<=n;++i) {
for(int j=ans[i];j<=100;++j) {
dp[i][j]=max(dp[i-1][j],dp[i-1][j-ans[i]]+1);
}
}
printf("%d\n",dp[n][100]);
return 0;
}
H. 程序设计:成绩查询系统
数学老师小y想写一个成绩查询系统,包含如下指令:
- insert [name] [score],向系统中插入一条信息,表示名字为name的学生的数学成绩为score。
- find [name],表示查找名字为name的学生的数学成绩。
注意有些同学可能会为了刷分多次选课,查询的时候给出最大成绩即可。学生的名字是由小写字母组成。成绩是一个 0 \ldots1000…100 的整数。
老师找到你,想你帮他完成这个系统。
输入格式
输入若干行,每行都是insert [name] [score]或者find [name]的形式,或一行end表示输入结束。输入行数不大于 1000,每个学生名字长度不大于 20 个字符。
输出格式
对于每个查询,输出查询的学生的最高成绩,如果系统中不存在该学生,输出 -1。
思路:map
代码:
/*
insert zhangsan 90
insert zhangsan 96
insert lisi 78
insert xiaoming 86
find xiaoming
find zhangsan
find jack
end
*/
#include<iostream>
#include<string>
#include<algorithm>
#include<map>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int main() {
string s;
map<string,int> a;
while(cin>>s) {
if(s[0]=='e') break;
else if(s[0]=='i') {
string name;
int score;
cin>>name>>score;
map<string,int>::iterator temp;
temp=a.find(name);
if(temp==a.end()) a.insert(make_pair(name,score));
else a[name]=max(a[name],score);
} else if(s[0]=='f') {
string name;
cin>>name;
map<string,int>::iterator temp;
temp=a.find(name);
if(temp==a.end()) {
cout<<"-1"<<endl;
} else {
cout<<temp->second<<endl;
}
}
}
return 0;
}
I. 程序设计:引爆炸弹
在一个 n×m 的方格地图上,某些方格上放置着炸弹。手动引爆一个炸弹以后,炸弹会把炸弹所在的行和列上的所有炸弹引爆,被引爆的炸弹又能引爆其他炸弹,这样连锁下去。
现在为了引爆地图上的所有炸弹,需要手动引爆其中一些炸弹,为了把危险程度降到最低,请算出最少手动引爆多少个炸弹可以把地图上的所有炸弹引爆。
输入格式
第一行输两个整数 n,m,用空格隔开。
接下来 n 行,每行输入一个长度为 m 的字符串,表示地图信息。0
表示没有炸弹,1
表示炸弹。
数据约定:
对于60% 的数据: 1≤n,m≤100;
对于 100% 的数据: 1≤n,m≤1000;
数据量比较大,不建议用cin
输入。
输出格式
输出一个整数,表示最少需要手动引爆的炸弹数。
思路:并查集
代码:
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=1005;
struct edge {
int from,to;
}Edge[maxn*maxn];
int pre[maxn];
bool cmp(const edge &a, const edge &b) {
if(a.from==b.from) return a.to<b.to;
return a.from<b.from;
}
int findfather(int x) {
if(pre[x]!=x) pre[x]=findfather(pre[x]);
return pre[x];
}
void change(int son, int f) {
if(pre[son]!=f) {
change(pre[son],f);
pre[son]=f;
}
}
int main() {
int n,m;
scanf("%d %d\n",&n,&m);
char s[m+1];
int index=0;
for(int i=0;i<n;++i) {
gets(s);
for(int j=0;j<m;++j) {
if(s[j]=='1') {
Edge[index].from=i;
Edge[index].to=j+n;
index++;
}
}
}
for(int i=0;i<maxn;++i) pre[i]=i;
sort(Edge,Edge+index,cmp);
for(int i=0;i<index;++i) {
int f1=findfather(Edge[i].from),f2=findfather(Edge[i].to);
if(f1!=f2) {
pre[f1]=f2;
}
}
set<int> ans;
for(int i=0;i<index;++i) {
ans.insert(findfather(Edge[i].from));
ans.insert(findfather(Edge[i].to));
}
int result=ans.size();
printf("%d\n",result);
return 0;
}
J. 程序设计:放置守卫
在一张 n 行 m 列的方格地图上放置一些守卫,每个守卫能守护上、左、右三个方向上相邻的方格和自己所在的方格。如下图,红色的方格放置守卫,绿色的方格为该守卫守护的区域。
现在要求在地图上放置若干个守卫,让每个方格至少被一个守卫守护(可以同时被多个守卫守护),但是有些方格上不能放置守卫(这个方格也需要被守护),求出最少需要多少个守卫才能满足条件。
输入格式
第一行输入两个整数 n,m。
接下来输入一个 n×m 的矩阵。矩阵中元素为 0 表示该位置不能放置守卫,为 1 表示该位置能放置守卫。元素之间用空格隔开。
数据约定:所有数据保证一定有一种方案满足条件。
对于 20% 的数据: 1≤n,m≤5;
对于 50% 的数据: 1≤n≤20,1≤m≤10;
对于100% 的数据:1≤n∗m≤1000,1≤m≤15。
输出格式
输出最少需要放置的守卫数量。
思路:轮廓线DP 我还不会啊QAQ