自测 160分
第一题 30分
第二题 100分
第三题 30分(后来100分 自己改的)
第四题 0分
第一题
十五的月亮
题目描述
假设一个每个月都是30天,用 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 表示一个月30天中的月亮的大小。
给出n天的月亮大小,请预测接下来一天的月亮的大小情况;变大的话输出UP,变小的话输出DOWN,如果无法预测请输出-1。
输入描述
第一行输入一个整数n,表示给出的n天。
第二行输入n个整数x,x表示这n天中的月亮大小。(0 <= x <= 15)
输出描述
月亮的变化情况,变大的话输出UP,变小的话输出DOWN,如果无法预测请输出-1。
输入样例
5
3 4 5 6 7
输出样例
UP
数据描述
30%的数据:n=1
100%的数据:1≤n≤92,0≤xi≤15
考试中想,定义两个计数器:cnt1和cnt2,cnt2用来计数上升,cnt1用来计数下降,如果cnt1==0那么输出UP,否则 如果cnt2==0那么输出DOWN,否则输出-1
错思路 判断数的大小。如果呈上升输出UP, 如果呈下降输出DOWN,既有上升又有下降输出-1
错代码
#include<iostream>
#include<cstdio>
using namespace std;
int main() {
int n,a[105],cnt1=0,cnt2=0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=2;i<=n;i++){
if(a[i]<a[i-1]) cnt1++;
else if(a[i]>a[i-1]) cnt2++;
}
if(cnt1==0) cout<<"UP";
else if(cnt2==0) cout<<"DOWN";
else if(cnt1!=0&&cnt2!=0) cout<<"-1";
return 0;
}
对思路 挨个枚举各种境况
对代码
#include<iostream>
#include<cstdio>
using namespace std;
int main() {
int n,a[105],cnt1=0,cnt2=0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
if(a[n]==0){
cout<<"UP";
}
else if(a[n]==15){
cout<<"DOWN";
}
else if(n==1){
cout<<-1;
}
else if(a[n]>a[n-1]){
cout<<"UP";
}
else if(a[n]<a[n-1]){
cout<<"DOWN";
}
return 0;
}
第二题
原码反码补码
题目描述
小可今天学习了原码反码补码的相关内容,想让你帮他写一个程序:
对于给定的二进制字符串原码,输出其对应的反码和补码。
原码转换成反码的规则:
原码的第一位为符号位,若符号位为 0,则反码与原码相同。若符号位为 1,则符号位不变,将其他位全部取反。
反码转换成补码的规则:
如果反码的符号位是0,则补码与反码相同,否则,补码等于反码+1 。
输入描述
输入一行,一个01字符串,表示原码
输出描述
输出两行:每行的字符数量和输入一样。
第一行表示二进制反码;
第二行表示二进制补码,如果补码位数高于原码位数,则高位溢出。
输入样例
1000
输出样例
1111
0000
数据描述
20%的数据下:符号位是0 。
100%的数据下:字符串长度不超过32 。
考试中想 因为长度不超过32 。所以要用string类型来存储。先判断是不是整数 如果是输出两遍s就可以了。如果不是那么先对除符号位以为的按位取反,输出一下并换行。然后定义一个来累加进位的变量jw,并附初始值为1,循环长度减1到0次,每次判断s[i]加jw是否是为'2',如果为是,那么 s[i]='0';jw=1;如果为否,那么s[i]=s[i]+jw;。最后输出s;
错思路 无
错代码 无
对思路 先判断是不是整数 如果是输出两遍s就可以了。如果不是那么先对除符号位以为的按位取反,输出一下并换行。然后在此基础上加1(记着处理进位),最后输出。
对代码
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
int main() {
string s;
cin>>s;
if(s[0]=='0'){
cout<<s<<endl<<s;
return 0;
}
else{
int l=s.size();
for(int i=1;i<l;i++){
if(s[i]=='0') s[i]='1';
else if(s[i]=='1') s[i]='0';
}
cout<<s<<endl;
int jw=1;
for(int i=l-1;i>=0;i--){
if(s[i]+jw=='2') {
s[i]='0';
jw=1;
}
else{
s[i]=s[i]+jw;
jw=0;
}
}
cout<<s;
}
return 0;
}
第三题
区间数位和
题目描述
对于给定的数字n,求1到n所有的数字,其十进制位的所有位的和是多少。
例如 n=12,则其答案为1+2+3+4+5+6+7+8+9+(1+0)+(1+1)+(1+2)=51
输入描述
第一行:输入一个正整数t,表示多组测试的样例组数。
接下来t行:每行输入一个正整数n,表述如题。
输出描述
对于每个n,输出一行一个答案。
输入样例
7
12
1
2
3
1434
2024
200000
输出样例
51
1
3
6
18465
28170
4600002
数据描述
30%的数据下:1≤t,n≤10^3
100%的数据下:1≤t≤10^5,1≤n≤10^6
考试中想 循环t次每次输入一个n,然后循环1~n次每次加数位和,最后输出。
错思路 循环t次每次输入一个n,然后循环1~n次每次加数位和,最后输出。
错代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long t,n;
int shuwei(int n){
int a=0;
while(n){
a+=n%10;
n/=10;
}
return a;
}
int main() {
scanf("%lld",&t);
while(t--){
long long sum=0;
scanf("%lld",&n);
for(int i=1;i<=n;i++){
sum+=shuwei(i);
}
printf("%lld\n",sum);
}
return 0;
}
对思路 打表
对代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long t,n,a[1000005];
int shuwei(int n){
int a=0;
while(n){
a+=n%10;
n/=10;
}
return a;
}
int main() {
scanf("%lld",&t);
a[1]=1;
for(int i=2;i<=1000000;i++){
a[i]=a[i-1]+shuwei(i);
}
while(t--){
scanf("%lld",&n);
printf("%lld\n",a[n]);
}
return 0;
}
第四题
双人博弈
题目描述
小可和达达正在打牌,他们俩每人都有n张牌,每张牌的大小是从0到9的。
每一轮他们俩每个人出一张牌,数字大的获胜。特殊的如果数字相同则为平局。
但是阴险狡诈的达达,已经知道了小可的出牌顺序为S。所以他可以调整自己的牌的顺序来应对小可的牌。
请问达达最少可以输多少次,最多可以赢多少次。
输入描述
第一行:输入一个正整数n,表示每个人的牌数。
第二行:输入一个长度为n的字符串,表示按照顺序排好的小可的牌。
第三行:输入达达的牌。
输出描述
达达最少可以输多少次,最多可以赢多少次。
输入样例
3
123
321
输出样例
0
2
数据描述
30%的数据:1≤n≤10
另有20%的数据:1≤n≤1000
100%的数据:1≤n≤10^5
考试中想 不咋会,打暴力
错思路 暴力
错代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long t,n,a[1000005];
bool cmp(int a,int b){
return a>b;
}
int main() {
int n,minn1=1000000,minn2=1000000,maxx1=-1,maxx2=-1,as[100005],as1[100005];
int cnt1=0,cnt2=0;
cin>>n;
string s,s1;
cin>>s>>s1;
for(int i=0;i<n;i++){
if(s[i]-'0'>maxx1) maxx1=s[i]-'0';
if(s[i]-'0'<minn1) minn1=s[i]-'0';
as[i+1]=s[i]-'0';
}
for(int i=0;i<n;i++){
if(s1[i]-'0'>maxx2) maxx2=s1[i]-'0';
if(s1[i]-'0'<minn2) minn2=s1[i]-'0';
as1[i+1]=s1[i]-'0';
}
if(maxx1<=minn2){
cout<<0<<"\n"<<n;
return 0;
}else if(maxx2<minn1){
cout<<n<<"\n"<<0;
return 0;
}
sort(as+1,as+1+n);
sort(as1+1,as1+1+n,cmp);
for(int i=1;i<=n;i++){
if(as[i]<as1[i]) cnt1++;
else if(as[i]>as1[i]) cnt2++;
}
cout<<cnt2<<"\n"<<cnt1;
return 0;
}
对思路 排序后双指针
对代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int main() {
char a[1000005],b[1000005];
int n,i=0,j=0,ans1=0,ans2=0;
cin>>n>>a>>b;
sort(a,a+n);
sort(b,b+n);
while(i<n&&j<n){
if(b[j]>=a[i]){
i++,j++;
}
else {
j++,ans1++;
}
}
i=j=0;
while(i<n&&j<n){
if(b[j]>a[i]){
ans2++;
i++,j++;
}
else {
j++;
}
}
cout<<ans1<<"\n"<<ans2;
return 0;
}
考后总结 这套题没有考到理想的分数,50分钟就交卷了,考了160分。如果再做30分钟可以再加上个70分,就230分了。吸取这次教训以后每次考试不能提前交卷了。