A1042 shuffling machine
1.可以使用字符数组来建立编号和花色的关系,若当前牌号为x,则mp[(x-1)/13]即为这张拍的花色,而(x-1)%13+1即为这张牌的数字。
2.设置两个数组,start[],end[],分别放置执行操作前的排序和执行操作后的排序,在执行完一次后,再让end[]覆盖start[]以此进行下一次排序操作,这样执行完成后数组start[]保存的就是最终的牌序。
这是自己写的,写得很罗嗦,思考了很久才发现问题在于自己只定义了一个数组,这样会导致牌序出现重复,总之这样做时完全错误的,必须用另一个数组来保存执行操作后的结果!
–已通过OJ
#include <cstdio>
int main() {
int k;
scanf("%d", &k);
int cards[55], cards_f[55]={0};
for(int i=0; i<55; i++) {
cards[i]=i; //牌的初始顺序
}
int order[55],temp; //order表示输入的次序
int u=k;
while(k--) {
for(int i=1; i<55; i++) {
if(u==k+1) scanf("%d", &order[i]);
//printf("order=%d\t", order);
cards_f[order[i]]=cards[i];
}
for(int i=1; i<55; i++) {
cards[i]=cards_f[i];
}
}
for(int i=1; i<55; i++) {
if(cards[i]<=13) {
printf("S%d", cards[i]);
} else if(cards[i]<=26) {
printf("H%d", cards[i]-13);
} else if(cards[i]<=39) {
printf("C%d", cards[i]-26);
} else if(cards[i]<=52) {
printf("D%d", cards[i]-39);
} else {
printf("J%d", cards[i]-52);
}
if(i<54) printf(" ");
}
return 0;
}
下面是书中的参考代码,非常简洁,
#include <cstdio>
const int N=54;
char mp[5] = {'S', 'H', 'C', 'D', 'J'}; //牌序与花色的对应关系
int start[N+1], end[N+1], next[N+1]; //其中next[]用来保存执行操作的顺序
int main() {
int k;
scanf("%d", &k);
for(int i=1; i<=N; i++) {
start[i]=i; //初始时牌的编号
}
for(int i=1; i<=N; i++) {
scanf("%d", &next[i]);
}
for(int step=0; step<k; step++) {
for(int i=1; i<=N; i++) {
end[next[i]]=start[i];
}
for(int i=1; i<=N; i++) {
start[i]=end[i];
}
}
for(int i=1; i<=N; i++) {
if(i!=1) printf(" ");
start[i]--;
printf("%c%d", mp[start[i]/13], start[i]%13+1);
}
return 0;
}
A1046 Shortest Distance
—最后一组数据运行超时,书中说是由于给定的M、N值太大,每次循环都要遍历一遍数组,导致运行超时。
此外,书中直接使用了swap(a,b)函数及min(a,b),需要在程序开头添加头文件:
#include <algorithm>
using namespace std;
algorithm头文件中包含了大量的函数,添加头文件后即可直接使用,
有如下函数:https://www.cnblogs.com/lgxZJ/p/6377437.html
#include <cstdio>
int main() {
int N; //N为出口个数
scanf("%d", &N);
int dist[N+1]={0}, M; //dist[]储存的是各出口之间的距离,M为输入的出口对数
for(int i=1; i<=N; i++) {
scanf("%d", &dist[i]);
}
scanf("%d", &M);
int a, b; //a,b分别是每次输入的两个出口
for(int i=0; i<M; i++) {
scanf("%d %d", &a, &b);
int temp;
if(a>b) {
temp=a;a=b;b=temp;
} else if(a==b) {
printf("0\n");break;
}
int min_1=0, min_2=0; //min_1表示a-b的直接距离,min_2表示b-5->a的距离
for(int j=a; j<b; j++) { //计算min_1
min_1 += dist[j];
}
for(int k=1; k<=N; k++) { //计算min_2
if(k<a || k>=b) {
min_2 += dist[k];
}
}
int min=min_1>min_2?min_2:min_1;
printf("%d", min);
if(i<M-1) printf("\n");
}
return 0;
}
修改后如下:
主要修改内容是把大循环内的访问dist[]数组的循环放在了外面,这样就不会导致运行超时!为了将这两个循环拿到大循环外面,因此新创立了一个数组dis_sum[],这个数组表示1号节点到i+1号节点顺时针的距离,这样在循环内部就可以直接调用这个数组dis_sum[b-1]-dsi[a-1]来计算出a到b的顺时针距离。
–已通过OJ
#include <cstdio>
int main() {
int N; //N为出口个数
scanf("%d", &N);
int dist[N+1]={0}, M, sum=0, dis_sum[N+1]={0}; //dist[]储存的是各出口之间的距离,M为输入的出口对数
for(int i=1; i<=N; i++) {
scanf("%d", &dist[i]);
sum += dist[i];
dis_sum[i]=sum;
}
scanf("%d", &M);
int a, b; //a,b分别是每次输入的两个出口
for(int i=0; i<M; i++) {
scanf("%d %d", &a, &b);
int temp;
if(a>b) {
temp=a;a=b;b=temp;
} else if(a==b) {
printf("0\n");break;
}
int min_1, min_2; //min_1表示a-b的直接距离,min_2表示b-5->a的距离
min_1=dis_sum[b-1]-dis_sum[a-1];
min_2=sum-min_1; //计算min_2
int min=min_1>min_2?min_2:min_1;
printf("%d", min);
if(i<M-1) printf("\n");
}
return 0;
}
A1065 A+B and C
问题:1.题目给定的ABC数据类型都超过了long long的数据类型能表达的范围,大于263 -1,且二者相加后更有可能出现溢出(溢出是指两个正数相加为负数或两个负数相加为正数),结果导致只通过了一个数据点。
2.关于各数据类型的字节数、范围:
对于64位编译器:
char-------1字节,范围是-128~127, 即-27 ~27 -1
short int --2字节,范围是-32768~32767, 即-215 ~215 -1
int----------4字节,范围是-2147483648~+2147483647,即-231 ~231 -1,109 以内都可以使用int
long long–8字节, 范围是-263 ~263 -1, 大约在1010 ~1018之间
unsigned long long–8字节,范围是0~264 -1
对于本题中的long long, 溢出的最小负数是-263 (由263对应),最大负数是-2(由264 -2对应),即可以知道,如果a+b>=263 ,则a+b>c,那么当a>0,b>0,a+b<0时必然有a+b>c,为true;
当a+b<-263 时,显然有a+b<c, 此时也会出现溢出,从263 (-263-1)到0(-264 ),因此当a<0,b<0,a+b>=0时有a+b<c,为false。
代码如下:
#include <cstdio>
int main() {
long long A, B, C;
int T;
scanf("%d", &T);
for(int i=1; i<=T; i++) {
scanf("%lld%lld%lld", &A, &B, &C);
if(A+B>C){
printf("Case #%d: true", i);
} else {
printf("Case #%d: false", i);
}
if(i<T) printf("\n");
}
return 0;
}
修改后如下:
已通过OJ
#include <cstdio>
int main() {
long long A, B, C;
int T;
scanf("%d", &T);
for(int i=1; i<=T; i++) {
scanf("%lld%lld%lld", &A, &B, &C);
bool flag;
long long res=A+B;
if(A>0 && B>0 &&res<0) flag=true; //正溢出情况
else if(A<0 && B<0 && res>=0) flag =false; //负溢出情况
else if(res>C) flag=true;
else flag=false;
if(flag){
printf("Case #%d: true", i);
} else {
printf("Case #%d: false", i);
}
if(i<T) printf("\n");
}
return 0;
}
A1002 A+B for Polynomials
只有两个数据点通过了。。。
#include <cstdio>
int main() {
double exp[1010]={0.0}; //保存指数i对应的系数
double a; //a为系数
int i; //i为指数
int n; //每行多项式的对数
int count=0;
for(int i=0; i<2; i++) {
scanf("%d", &n);
for(int j=0; j<n; j++){
scanf("%d%lf", &i, &a);
exp[i] += a;
}
}
//printf("a[0]=%.1f\n", exp[0]);
int flag=1;
for(int i=0; i<=1000; i++) {
if(exp[i]>=1e-6 || exp[i]<=-1e-6) {
count ++;
}
}
printf("%d ", count);
for(int i=1000; i>=0; i--) {
if(exp[i]>=1e-6||exp[i]<=-1e-6) {
if(flag==1) {
printf("%d %.1f", i, exp[i]);
flag=0;
} else {
printf(" %d %.1f", i, exp[i]);
}
}
}
return 0;
}
问题:1.第一个循环内的指数写成了与循环变量相同的字母!服了,我好蠢。
#include <cstdio>
int main() {
double exp[1010]={}; //保存指数i对应的系数
double a; //a为系数
int k; //k为指数
int n; //每行多项式的对数
int count=0;
for(int i=0; i<2; i++) {
scanf("%d", &n);
for(int j=0; j<n; j++){
scanf("%d%lf", &k, &a);
exp[k] += a;
}
}
//printf("a[0]=%.1f\n", exp[0]);
for(int i=0; i<=1000; i++) {
if(exp[i]!=0) {
count ++;
}
}
printf("%d", count);
for(int i=1000; i>=0; i--) {
if(exp[i]!=0) {
printf(" %d %.1f", i, exp[i]);
}
}
return 0;
}
A1009 Product of Polynomials
已通过OJ
#include <cstdio>
const int maxsize=2010;
int main() {
int k; //每行多项式对数
double a1[maxsize+1]={0}, a2[maxsize+1]={0};
//其中ai保存第一行读取的多项式,a2保存第二行每项和第一行相乘后的结果
scanf("%d", &k);
int exp;
double coe;
for(int i=0; i<k; i++) {
scanf("%d%lf", &exp, &coe);
a1[exp]=coe;
}
scanf("%d", &k);
for(int i=0; i<k; i++) {
scanf("%d%lf", &exp, &coe);
for(int j=0; j<maxsize; j++) {
if(a1[j]!=0) {
a2[j+exp]=a2[j+exp]+coe*a1[j];
}
}
}
int count=0; //计数不为零的项
for(int i=0; i<maxsize; i++) {
if(a2[i]!=0) {
count++;
}
}
printf("%d", count);
for(int i=maxsize; i>=0; i--) {
if(a2[i]!=0) {
printf(" %d %.1f", i, a2[i]);
}
}
return 0;
}
A1011 World Cup Betting
#include <cstdio>
int main() {
char sub[3]={'W', 'T', 'L'}; //最后输出时调用的字符数组
double odds[3][3]; //保存概率的二维数组
for(int i=0; i<3; i++) { //读入数据
for(int j=0; j<3; j++) {
scanf("%lf", &odds[i][j]);
}
}
int seq[3]; //保存最大概率对应的序号,对应着WTL
double max_odd[3]={0}; //保存每行最大概率
for(int i=0; i<3; i++) {
for(int j=0; j<3; j++) {
if(odds[i][j]>max_odd[i]) {
max_odd[i]=odds[i][j];
seq[i]=j;
}
}
}
double profit;
profit=(max_odd[0]*max_odd[1]*max_odd[2]*0.65-1)*2;
for(int i=0; i<3; i++) {
printf("%c ", sub[seq[i]]);
}
printf("%.2f", profit);
return 0;
}
A1006 Sign In and Sign Out
此题和B1028类似,基本思路是一样的
#include <cstdio>
struct sign_in_out{
char id[16];
};
int main() {
int m; //m表示输入的学生信息个数
scanf("%d", &m);
sign_in_out info[m];
int min_unlock=23*60*60+59*60+59;
int max_lock=0;
int min_num, max_num; //表示最小和最大的total对应的位序
for(int i=0; i<m; i++) {
int hh_in,mm_in,ss_in;
int hh_out,mm_out, ss_out;
int total_in, total_out; //表示时分秒之和
scanf("%s%d:%d:%d", &info[i].id, &hh_in, &mm_in, &ss_in);
scanf("%d:%d:%d", &hh_out, &mm_out, &ss_out);
total_in=hh_in*3600+mm_in*60+ss_in;
total_out=hh_out*3600+mm_out*60+ss_out;
if(total_in<=min_unlock){
min_unlock=total_in;
min_num=i;
}
if(total_out>=max_lock){
max_lock=total_out;
max_num=i;
}
}
printf("%s %s", info[min_num].id, info[max_num].id);
return 0;
}
对于头文件:
1.#include :C++的输入输出是由iostream标准库提供的,iostream库定义了以下三个标准流对象:
①cin,表示标准输入(standard input)的istream类对象。cin使我们可以从设备读入数据。
②cout,表示标准输出(standard output)的ostream类对象。cout使我们可以向设备输出或者写数据。
3)cerr,表示标准错误(standard error)的osttream类对象。cerr是导出程序错误消息的地方,它只能允许向屏幕设备写数据。
输出主要由重载的左移操作符(<<)来完成,输入主要由重载的右移操作符(>>)完成:
a表示将数据放入a对象中。
<<a表示将a对象中存储的数据拿出。
2.#include
3.using namespcae std:
后缀为.h的头文件C++标注已经明确提出不支持了。早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,C++标准为了和C区别开,也为了正确地使用命名空间,规定头文件不使用后缀.h。因此,当使用<iostream.h>时,相当于在C中调用库函数,使用的是全局命名空间,也就是早期的C++实现。当使用时,该头文件没有定义全局命名空间,必须使用namespace std,这样才能使用类似于cout这样的C++标识符。
namespace是指标识符的各种可见范围。
作者:PG-aholic
来源:CSDN
原文:https://blog.csdn.net/fsz520w/article/details/82561795
版权声明:本文为博主原创文章,转载请附上博文链接!
书中算法如下:
#include <cstdio>
#include <iostream>
using namespace std;
struct pnode{
char id[20];
int hh,mm,ss;
}temp,ans1,ans2;
bool great(pnode node1, pnode node2) { //node1时间大于node2时间返回true
if(node1.hh!=node2.hh) return node1.hh>=node2.hh;
if(node1.mm!=node2.mm) return node1.mm>=node2.mm;
return node1.ss>=node2.ss;
}
int main() {
int n;
scanf("%d", &n);
ans1.hh=24, ans1.mm=60, ans1.ss=60;
ans2.hh=0, ans2.mm=0, ans2.ss=0;
for(int i=0; i<n; i++) {
//先读入签到时间
scanf("%s %d:%d:%d", &temp.id, &temp.hh, &temp.mm, &temp.ss);
if(great(temp,ans1)==false) {
ans1=temp;
}
//读入签离时间
scanf("%d:%d:%d", &temp.hh, &temp.mm,&temp.ss);
if(great(temp, ans2)==true) ans2=temp;
}
printf("%s %s", ans1.id, ans2.id);
}
A1036 Boys vs Girls
已通过OJ
#include <cstdio>
#include <iostream>
using namespace std;
struct student{
char name[11];
char gender;
char id[11];
int grade;
}temp,ans_f,ans_m;
int main() {
int m; //m表示输入学生的个数
scanf("%d", &m);
ans_f.grade=0, ans_m.grade=100;
int count_f=0, count_m=0; //计数输入男女学生个数
for(int i=0; i<m; i++) {
scanf("%s %c %s %d", &temp.name, &temp.gender, &temp.id, &temp.grade);
if(temp.gender=='F'&&temp.grade>=ans_f.grade) {
ans_f=temp;
count_f++;
}
if(temp.gender=='M'&&temp.grade<=ans_m.grade) {
ans_m=temp;
count_m++;
}
}
if(count_f!=0) {
printf("%s %s\n", ans_f.name, ans_f.id);
} else{
printf("Absent\n");
}
if(count_m!=0) {
printf("%s %s\n", ans_m.name, ans_m.id);
} else {
printf("Absent\n");
}
if(count_f!=0&&count_m!=0) {
printf("%d", ans_f.grade-ans_m.grade);
}else {
printf("NA");
}
return 0;
}
值得注意的是,书中在赋值给ans_f.grade和ans_m.grade时分别赋了-1和101,这样在后面输出特殊情况的时候就不用单独定义count_f和count_m了,更加简洁。
A1031 Hello World For U
1.两个测试点显示格式错误
发现是由于计算n1,n2,n3的公式不对,迷,每次找规律都不会找,我好蠢。
n1,n3是(N+2)/3向下取整,
n2由公式计算得到,n2=n+2-n1-n3,修改之后即可通过OJ
2.书中是用二维数组输出的,
题目中给定的n1,n3的限定范围实际上就是n1=n3<=n2, 抓住这个寻找规律,就不会出错了。
3.除了用这种找规律的方式计算n1,n2,n3的值,还可以用枚举的方法寻找这三个数,我们知道当n2比较小的时候是不符合题目的,因此可以从小到大枚举,而相应的n1,n3则从大到小变化,直到n2>=n3=n1这个临界值,即为这三个数!注意这种方式要考虑(N+2-n2)/2无法整除的情况!
int n1, n2, n3;
for(n2=0; n2<=N; n2++) {
if((N+2-n2)%2==0) {
n1=n3=(N+2-n2)/2;
}
}
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
int main() {
char str[90];
scanf("%s", str);
int length=strlen(str); //length为字符串长度
int n1, n2, n3;
n1=n3=floor((length+2)/3.0);
n2=length+2-n1-n3;
int i, j=length-1;
for(i=0; i<n1-1; i++) { //打印第一列与最后一列的字符
printf("%c", str[i]);
for(int k=0; k<n2-2; k++) { //打印中间的空格
printf(" ");
}
printf("%c", str[j--]);
printf("\n");
}
for(; i<=j; i++) {
printf("%c", str[i]);
}
return 0;
}
A1019 General Palindromic Number
#include <cstdio>
int main() {
int n, b;
scanf("%d %d", &n, &b);
int z[200], num=0;
do{
z[num++]=n%b;
n=n/b;
}while(n!=0);
int i;
for(i=0; i<=num/2; i++) {
if(z[i]!=z[num-i-1]) {
break;
}
}
if(i<=num/2) {
printf("No\n");
} else {
printf("Yes\n");
}
for(int j=num-1; j>=0; j--) {
printf("%d", z[j]);
if(j>0) printf(" ");
}
return 0;
}
A1027 Colors in Mars
#include <cstdio>
char digits[13]={'0', '1','2','3','4','5','6','7','8','9','A','B','C'};
void digit_change(int n, int z[], int i) { //i表示在数组中的存储位置
int num=i;
do{
z[num++]=n%13;
n=n/13;
}while(n!=0);
}
int main() {
int n1, n2, n3;
scanf("%d %d %d", &n1, &n2, &n3);
int z[10];
digit_change(n1, z, 0);
digit_change(n2, z, 2);
digit_change(n3, z, 4);
for(int i=0; i<6; i+=2) {
int temp=z[i];
z[i]=z[i+1];
z[i+1]=temp;
}
printf("#");
for(int i=0; i<6;i++) {
printf("%c", digits[z[i]]);
}
return 0;
}
书中的简略写法:
#include <cstdio>
char digits[13]={'0', '1','2','3','4','5','6','7','8','9','A','B','C'};
int main() {
int n1, n2, n3;
scanf("%d %d %d", &n1, &n2, &n3);
printf("#");
printf("%c%c", digits[n1/13], digits[n1%13]);
printf("%c%c", digits[n2/13], digits[n2%13]);
printf("%c%c", digits[n3/13], digits[n3%13]);
return 0;
}
A1058 A+B in Hogwarts
注意:如果用int类型数据的话,有一组测试点显示无法通过,溢出了,因此使用long long!
#include <cstdio>
int main() {
long long a_g, a_s, a_k, a_knuts;
long long b_g, b_s, b_k, b_knuts;
long long c_g, c_s, c_k, c_knuts;
scanf("%lld.%lld.%lld %lld.%lld.%lld", &a_g, &a_s, &a_k, &b_g, &b_s, &b_k);
a_knuts=(a_g*17+a_s)*29+a_k;
b_knuts=(b_g*17+b_s)*29+b_k;
c_knuts=a_knuts+b_knuts;
c_k=c_knuts%29;
c_g=c_knuts/29/17;
c_s=c_knuts/29-c_g*17;
printf("%lld.%lld.%lld", c_g, c_s, c_k);
return 0;
}
A1001 A+B Format
已通过OJ—但是代码太繁琐了,逻辑非常混乱。各种边界情况一开始没有想到,或者想到了却忘记写进去,晕,另外负数转化为正数这个方法也给忘了。
注意:
1.int转str:除了用循环除10之外,还可以直接用sprintf(str,"%d", n)这个函数。<-----
2.str转int:可用sscanf(str, “%d”, &n);---->
另外题目规定了a,b都在106 以内,因此也可以考虑用枚举的方式!这样最快。如下:
#include <cstdio>
int main() {
int a, b, sum;
scanf("%d%d", &a, &b);
sum=a+b;
if(sum<0) {
printf("-");
sum *= -1;
}
if(sum>=1000000) {
printf("%d,%03d,%03d", sum/1000000, sum%1000000/1000, sum%1000);
}else if(sum>=1000){
printf("%d,%03d", sum/1000, sum%1000);
} else {
printf("%d", sum);
}
return 0;
}
#include <cstdio>
#include <cstring>
int main() {
int a, b, c;
scanf("%d %d", &a, &b);
c=a+b;
char str[15];
sprintf(str, "%d", c);
int len=strlen(str), num_comma, pre_comma;
if(c==0) {
printf("0");
return 0;
}
if(str[0]=='-') {
num_comma=(len-2)/3; //负数的时候的逗号数量
if(num_comma==0) {
printf("%s", str);
return 0;
}
printf("-");
pre_comma=len-1-num_comma*3; //第一个逗号前的数字个数
int i=1;
while(str[i]!='\0') {
for(; i<=pre_comma; i++) {
printf("%c", str[i]);
}
if(i==pre_comma+1) {
printf(",");
}
for(int j=0; j<3; j++) {
printf("%c", str[i]);i++;
}
if(str[i]!='\0') printf(",");
}
} else {
num_comma=(len-1)/3;
if(num_comma==0) {
printf("%s", str);
return 0;
}
pre_comma=len-num_comma*3;
int i=0;
while(str[i]!='\0') {
for(;i<pre_comma; i++) {
printf("%c", str[i]);
}
if(i==pre_comma) printf(",");
for(int j=0; j<3; j++) {
printf("%c", str[i]);i++;
}
if(str[i]!='\0') printf(",");
}
}
return 0;
}
书中代码是在考虑了a,b的范围后给出的代码:
#include <cstdio>
int num[10];
int main() {
int a, b, sum;
scanf("%d %d", &a, &b);
sum=a+b;
if(sum<0) {
printf("-");
sum *= -1;
}
int len=0;
do{
num[len++]=sum%10;
sum /= 10;
}while(sum!=0);
for(int k=len-1; k>=0; k--) {
printf("%d", num[k]);
if(k>0 && k%3==0) printf(",");
}
return 0;
}
A1005 Spell It Right
#include <cstdio>
#include <cstring>
char num_English[10][10]={"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
int main() {
char number[110];
scanf("%s", number);
int sum=0, len=strlen(number);
for(int i=0; i<len; i++) {
sum += number[i]-'0';
}
int num=0, digits[15]; //用来保存sum的每一位
do{
digits[num++] = sum%10;
sum /= 10;
} while(sum!=0);
for(int i=num-1; i>=0; i--) { //从高位到低位读取
printf("%s", num_English[digits[i]]);
if(i>0) printf(" ");
}
return 0;
}
或者采用如下递归的方式:
只要得到了sum的值,然后再主程序调用dfs(sum)即可得到答案!
void dfs(int n) {
if(n/10==0) {
printf("%s", num_English[n%10]);
return;
}
dfs(n/10);
printf(" %s", num_English[n%10]);
}
A1035 Password
已通过OJ
#include <cstdio>
#include <cstring>
void substitute(char a[]) {
int len=strlen(a), flag=0; //1表示被修改过,
for(int i=0; i<len; i++) {
if(a[i]=='1') {
a[i]='@'; flag=1;
} else if(a[i]=='0') {
a[i]='%';flag=1;
} else if(a[i]=='l') {
a[i]='L';flag=1;
} else if(a[i]=='O') {
a[i]='o';flag=1;
}
if(flag==1) {
a[11]='1'; //1表示被修改过
}
flag=0;
}
}
int main() {
int N; //表示输入的信息对数
scanf("%d", &N);
char str_password[N][12], str_name[N][12];
for(int i=0; i<N; i++) {
scanf("%s %s", str_name[i], str_password[i]);
substitute(str_password[i]);
}
int sum=0; //表示被修改过的数目
for(int i=0; i<N; i++) {
if(str_password[i][11]=='1') sum++;
}
if(sum==0 && N==1) {
printf("There is 1 account and no account is modified");
} else if(sum==0 && N>1) {
printf("There are %d accounts and no account is modified", N);
} else {
printf("%d\n", sum);
while(sum>0) {
for(int i=0; i<N; i++) {
if(str_password[i][11]=='1') {
printf("%s %s\n", str_name[i], str_password[i]);
sum--;
}
}
}
}
return 0;
}
A 1077 Kuchiguse
问题:有一个测试点没有通过,暂时不知道原因是什么
以下为代码:
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int main() {
int N; //表示输入的字符串行数
scanf("%d", &N);
getchar(); //吸收掉N后面的换行符号
char str[N][260];
for(int i=0; i<N; i++) {
cin.getline(str[i], 266);
}
int len_str[N]; //表示存储字符串长度的数组
for(int i=0; i<N; i++) {
len_str[i]=strlen(str[i]);
}
int kuchi=-1; //表示第一个字符串与第二个字符串倒着看相同部分的位序
for(int i=len_str[0]-1, j=len_str[1]-1; i>=0 && j>=0; i--, j--) {
if(str[0][i]==str[1][j]) {
kuchi=i; //表示找到了kuchi的第一个字符在零号数组中的位置
} else {
break;
}
}
if(kuchi==-1) {
printf("nai");
exit(0);
} else {
int len_kuchi=len_str[0]-kuchi; //表示kuchi的长度
int k_0=kuchi; //表示0号数组的kuchi在其中的位序
for(int i=2; i<N; i++) {
for(int j=len_str[i]-len_kuchi; j<len_str[i]; j++) {
if(str[0][k_0]!=str[i][j]) {
printf("nai");
exit(0); //如果不等,直接结束程序
}
k_0++;
}
k_0=kuchi;
}
}
for(int i=kuchi; i<len_str[0]; i++) {
printf("%c", str[0][i]);
}
return 0;
}
本来书中代码有一个测试点是无法通过的, 发现把书中代码的字符串长度增加到260后编译就通过了,----迷。
以下为书中代码:
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int n, minlen=260, ans=0;
char s[100][260];
int main() {
scanf("%d", &n);
getchar(); //无论是用gets()还是cin.getline()都需要这一句
for(int i=0; i<n; i++) {
cin.getline(s[i], 260);
int len=strlen(s[i]);
if(len<minlen) minlen=len;
for(int j=0; j<len/2; j++) { //表示将所有字符串反转,便于比较
char temp=s[i][j];
s[i][j]=s[i][len-j-1];
s[i][len-j-1]=temp;
}
}
for(int i=0; i<minlen; i++) {
char c=s[0][i];
bool same=true;
for(int j=1; j<n; j++) {
if(c!=s[j][i]) {
same=false;
break;
}
}
if(same) ans++;
else break;
}
if(ans) {
for(int i=ans-1; i>=0; i--) {
printf("%c", s[0][i]);
}
} else {
printf("nai");
}
return 0;
}
A1082 Read Number in Chinese
问题:1.这题太繁琐了,太多个例,规律很难找啊,写了好久还是发现一堆问题没解决。?感觉自己好笨
2.如果尝试用枚举的方法解这道题也是不太可行的,例子不同,打印的东西也有很大差异。
3.主要思路是把数按节(每节四位,个十百千)分成几个小节,每个节的输出思路其实是一样的,即对于零的处理逻辑是相通的,在该节中,某个非零位前(不包括千位)如果有零的话,那么就需要在该非零位的发音前多一个零。节后的末尾根据具体情况输出亿万,为了便于代码编写,将亿万的输出写在节内数字打印的循环外面,根据是否有零及不是个位就输出亿万。。。。。
以下为书中代码:
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
char num[10][5]={"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
char wei[5][5]={"Shi", "Bai","Qian", "Wan", "Yi"};
int main() {
char str[15];
cin.getline(str, 15);
int len=strlen(str);
int left=0, right=len-1;
if(str[0]=='-') {
printf("Fu");
left++;
}
while(left+4<=right){
right-=4;
}
while(left<len) {
bool flag=false;
bool isPrint=false;
while(left<=right) {
if(left>0 && str[left]=='0') {
flag=true;
} else {
if(flag==true) {
printf(" ling");
flag=false;
}
if(left>0) printf(" ");
printf("%s", num[str[left]-'0']);
isPrint=true;
if(left!=right) {
printf(" %s", wei[right-left-1]);
}
}
left++;
}
if(isPrint==true && right!=len-1) {
printf(" %s", wei[(len-1-right)/4+2]);
}
right+=4;
}
return 0;
}
A1025 PAT Ranking
最后一个测试点无法通过,显示段错误.
问题:1.注意题目要求,最大容量应为100*300, 因此最好比30000大,这样就不会出现段错误
2.当把下面的代码的info[]改好了大小后,仍然无法通过最后一个测试点,显示答案错误,估计是因为将registration number 以long long 的形式输入输出的时候出了问题,当改成以字符串的形式输入输出的时候,通过OJ了,这也有点迷,因为题目明确说了这个数字是13位的啊,理论上说long long 应该完全没有问题啊。GU
以下为代码:
#include <cstdio>
#include <algorithm>
using namespace std;
struct Student{
long long regi_num;
int score;
int location;
int local_rank;
int final_rank;
}info[30010];
bool cmp(Student a, Student b) { //比较函数
if(a.score!=b.score) return a.score>b.score;
else return a.regi_num<b.regi_num;
}
int main() {
int loca;
scanf("%d", &loca);
int count=0; //表示读入的所有行数
for(int i=1; i<=loca; i++) { //i表示测试发生的地点
int K; //表示读入的行数
scanf("%d", &K);
count += K;
for(int j=count-K; j<count; j++) {
scanf("%lld %d", &info[j].regi_num, &info[j].score);
info[j].location=i;
}
sort(info+count-K, info+count, cmp); //局部排序
info[count-K].local_rank=1;
for(int m=count-K+1; m<count; m++) {
if(info[m].score==info[m-1].score) {
info[m].local_rank=info[m-1].local_rank;
} else {
info[m].local_rank=m+1+K-count;
}
}
}
sort(info, info+count, cmp);
info[0].final_rank=1;
for(int i=1; i<count; i++) { //表示输入排名
if(info[i].score==info[i-1].score) {
info[i].final_rank=info[i-1].final_rank;
} else {
info[i].final_rank=i+1;
}
}
printf("%d\n", count);
for(int i=0 ;i<count; i++) {
printf("%lld %d %d %d\n", info[i].regi_num, info[i].final_rank, info[i].location, info[i].local_rank);
}
return 0;
}
以下为正确代码,已通过OJ
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct Student{
char regi_num[15];
int score;
int location;
int local_rank;
int final_rank;
}info[1000];
bool cmp(Student a, Student b) { //比较函数
if(a.score!=b.score) return a.score>b.score;
else return strcmp(a.regi_num, b.regi_num)<0;
}
int main() {
int loca;
scanf("%d", &loca);
int count=0; //表示读入的所有行数
for(int i=1; i<=loca; i++) { //i表示测试发生的地点
int K; //表示读入的行数
scanf("%d", &K);
count += K;
for(int j=count-K; j<count; j++) {
scanf("%s %d", info[j].regi_num, &info[j].score);
info[j].location=i;
}
sort(info+count-K, info+count, cmp); //局部排序
info[count-K].local_rank=1;
for(int m=count-K+1; m<count; m++) {
if(info[m].score==info[m-1].score) {
info[m].local_rank=info[m-1].local_rank;
} else {
info[m].local_rank=m+1+K-count;
}
}
}
sort(info, info+count, cmp);
info[0].final_rank=1;
for(int i=1; i<count; i++) { //表示输入排名
if(info[i].score==info[i-1].score) {
info[i].final_rank=info[i-1].final_rank;
} else {
info[i].final_rank=i+1;
}
}
printf("%d\n", count);
for(int i=0 ;i<count; i++) {
printf("%s %d %d %d\n", info[i].regi_num, info[i].final_rank, info[i].location, info[i].local_rank);
}
return 0;
}