codeup 1934
http://codeup.cn/problem.php?cid=100000576&pid=1
1.题目要求输入格式中为多组数据,即多点测试,考虑while–EOF
已通过测试
#include <cstdio>
int main() {
int n; //n表示输入的数的个数
while(scanf("%d", &n)!=EOF) {
int a[n];
for(int i=0; i<n; i++) {
scanf("%d", &a[i]);
}
int x, j;
scanf("%d", &x);
for(j=0; j<n; j++) {
if(a[j]==x) {
printf("%d\n", j);
break;
}
}
if(j==n) {
printf("-1\n");
}
}
return 0;
}
codeup 1932问题 A: 统计同成绩学生人数
已通过OJ
#include <cstdio>
#include <iostream>
using namespace std;
int main() {
int n; //表示输入学生的人数
scanf("%d", &n);
while(n!=0) {
int grade[n];
for(int i=0; i<n; i++) {
scanf("%d", &grade[i]);
}
int x,count=0; //x表示要查找的成绩 ,count表示相应成绩的人数
scanf("%d", &x);
for(int j=0; j<n; j++) {
if(grade[j]==x) count++;
}
printf("%d\n", count);
scanf("%d", &n);
}
return 0;
}
Codeup 1935问题 C: 查找学生信息
可以通过样例,但始终无法通过OJ,不知道哪一步思考错了,
最后在讨论区发现这题太坑了
问题:
1.题目没说是不是多点测试,实际是多点测试
2.题目没有说name[]占多大位置,因此最好开100的空间
3.题目没说id的大小及输出方式,因此根据输入来调整输出
所以此处就要用到sscanf(str, “%d”, &n)用来把字符串转化为整数
另外ssprintf(str, “%d”, n)表示把n以%d的格式写到str字符数组中。
4.另外,在考虑如何筛选已输入的学号和未输入的学号时,提供一个int tags[n+1]={0};每当扫描到一个id,就让tags[id]=1。
以下为通过OJ的代码
#include <cstdio>
#include <iostream>
using namespace std;
struct student{
char name[100];
char gender[100];
int num;
};
int main() {
int n; //表示学生人数
int id;
while(scanf("%d", &n)!=EOF){
student info[n+1];
int tags[n+1]={0};
for(int i=0; i<n; i++) {
scanf("%d", &id);
scanf(" %s %s %d", &info[id].name, &info[id].gender, &info[id].num);
tags[id]=1;
}
int m; //表示要输出的学生个数
scanf("%d", &m);
char id_find[20]; //表示即将要查找的学号
for(int j=0; j<m; j++) {
scanf("%s", id_find);
sscanf(id_find, "%d", &id);
if(tags[id]) {
printf("%s %s %s %d\n", id_find, info[id].name, info[id].gender, info[id].num);
} else {
printf("No Answer!\n");
}
}
}
return 0;
}
Codeup 1937问题 D: 查找
已通过OJ
#include <cstdio>
#include <iostream>
using namespace std;
int main() {
int n;
while(scanf("%d", &n)!=EOF) {
int tag=0, num_in[n];
for(int i=0; i<n; i++) {
scanf("%d", &num_in[i]);
}
int m; //表示要搜寻的数字的个数
int num_out; //表示要搜寻的数字
scanf("%d", &m);
for(int j=0; j<m; j++) {
scanf("%d", &num_out);
for(int i=0; i<n; i++) {
if(num_in[i]==num_out){
tag=1;
}
}
if(tag) {
printf("YES\n");
} else{
printf("NO\n");
}
tag=0;
}
}
return 0;
}
Codeup 2020问题 E: 学生查询
题目虽然写着输出m行,但实际只是输出一行而已,否则程序也没法写了。
#include <cstdio>
#include <iostream>
using namespace std;
struct Student{
char name[100];
char sex[20];
int age;
};
int main() {
int m; //表示样例个数
scanf("%d", &m);
while(m--) {
int n; //表示输入的学生个数
scanf("%d", &n);
Student info[n+1];
int id; //表示学生学号-位序
for(int i=0; i<n; i++) {
scanf("%d", &id);
scanf(" %s %s %d", &info[id].name, &info[id].sex, &info[id].age);
}
scanf("%d", &id);
printf("%d %s %s %d\n", id, info[id].name, info[id].sex, info[id].age);
}
return 0;
}
Codeup 1933问题 A: 输出梯形
已通过OJ
#include <cstdio>
int main() {
int h; //梯形的高及上底
char c='*'; //填充字符
while(scanf("%d", &h)!=EOF) {
for(int i=1; i<=h; i++) {
for(int j=0; j<2*h-2*i; j++) { //打印空格
printf(" ");
}
for(int j=0; j<h+2*(i-1); j++) {
printf("%c",c);
}
printf("\n");
}
}
return 0;
}
Codeup 2003问题 C: 等腰梯形
已通过OJ
#include <cstdio>
int main() {
int m; //表示样例个数
scanf("%d", &m);
char c='*';
while(m--) {
int h; //表示、等腰梯形高及上底长
scanf("%d", &h);
for(int i=1; i<=h; i++) {
for(int j=0; j<h-i; j++) { //输出空格
printf(" ");
}
for(int j=0; j<h+(i-1)*2; j++) {
printf("%c", c);
}
printf("\n");
}
}
return 0;
}
3.4日期处理
Codeup 1928问题 A: 日期差值
这个问题实在是太复杂了!
问题:
1.书中把月份对应的天数用了拍一个二维数组month[13][2]来表示其中第二维的0表示平年,1表示闰年
2.是平年还是闰年用一个函数写出,闰年是值能被400整除或者能被四整除且不能被100整除,同时返回0或1,0是闰年,1是平年
3.要想得到两个日期相差的天数,可以让d1++,并判断month是否等于month[m1][isleap(y1)]+1,如果等于,则让month++,且d1=1,然后判断month是否等于13,如果等于的话,就让y1++,且m1=1,直到两个日期的年月日完全相等,
因此循环的条件是
4.注意应保证time1小于time2,如果相反的话,则需要交换。
while(!(y1==y2&&m1==m2&&d1==d2)){
}
//或者把!放进去
while(y1<y2 ||m1<m2||d1<d2){
}
#include <cstdio>
int month[13][2]={{0,0},{31,31},{28,29}, {31,31},{30, 30},
{31,31},{30,30},{31,31},{31,31},{30,30},{31,31},{30,30},{31,31}};
bool isleap(int year) {
return ((year%4==0 && year%100!=0)|| (year%400==0));
}
int main() {
int time1,time2;
int y1,m1,d1,y2,m2,d2;
while(scanf("%d%d", &time1, &time2)!=EOF){
if(time1>time2){
int temp=time1;
time1=time2;
time2=temp;
}
y1=time1/10000, m1=time1%10000/100, d1=time1%100;
y2=time2/10000, m2=time2%10000/100, d2=time2%100;
int ans=1;
while( y1<y2 || m1<m2 || d1<d2 ) {
d1++;
if(d1==month[m1][isleap(y1)]+1){
m1++;
d1=1;
}
if(m1==13){
y1++;
m1=1;
}
ans++;
}
printf("%d\n", ans);
}
return 0;
}
Codeup 1929 问题 B: Day of Week
感觉自己没写错啊,可是无法通过,不知道问题在哪里!
#include <cstdio>
#include <cstring>
char month_English[13][20]={{'0'},"January","Febrary","March","April","May","June","July","August","September","October","November","December"};
char week_English[7][20]={"Monday","Sunday","Saturday","Friday","Thursday","Wednesday","Tuesday"};
char month[13][2]={{0,0},{31,31},{28,29},{31,31},{30,30},{31,31},{30,30},{31,31},{31,31},{30,30},{31,31},{30,30},{31,31}};
bool isleap(int year){
return year%4==0 && year%100!=0 || year%400==0;
}
int day1=1,month1=7,year1=2019; //表示对照时间,用以与输入时间相减得到相差天数
bool great_date(int day, int month, int year) { //输入时间小于对照时间返回1,否则返回0
if(year!=year1) return year<=year1;
if(month!=month1) return month<month1;
else return day<day1;
}
int main() {
int day1=1,month1=7,year1=2019; //表示对照时间,对照时间为周一,用以与输入时间相减得到相差天数
int day2,month2,year2;
char mon[20];
while(scanf("%d %s %d", &day2, mon, &year2)!=EOF) {
for(int i=1; i<13; i++) { //查找第二个时间对应的月份的数字
if(strcmp(mon, month_English[i])==0) {
month2=i;
}
}
// printf("day2=%d, month2=%d, year2=%d, date_input=%d\n", day2, month2, year2,great_date(21, 12, 2012));
int count=0;
int temp=great_date(day2, month2, year2);
if(temp) { //如果输入时间比对照时间小
while(year2<year1 || month2<month1 || day2<day1) { //循环计算二者相差时间
day2++;
if(day2==month[month2][isleap(year2)]+1) {
month2++;day2=1;
}
if(month2==13) {
year2++;month2=1;
}
count++;
}
}else {
while(year1<year2 || month1<month2 || day1<day2) { //循环计算二者相差时间
day1++;
if(day1==month[month1][isleap(year1)]+1) {
month1++;day1=1;
}
if(month1==13) {
year1++;month1=1;
}
count++;
}
}
printf("count=%d\n", count);
if(temp) {
printf("%s\n", week_English[count%7]);
} else {
printf("%s\n", week_English[(7-count%7)%7]);
}
day1=1; month1=7; year1=2019;
}
return 0;
}
别人写的正确答案 用了一个日期转星期的公式! 基姆拉尔森计算公式:通过日期判断是星期几
W=(d+2m+3(m+1)/5+y+y/4-y/100+y/400)%7 在公式中d表示日期中的日数,m表示月份数,y表示年数。
注意:在公式中有个与其他公式不同的地方:
把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。
#include <iostream>
using namespace std;
inline const int dateToWeekI(int y, int m, int d)
{
//返回正确的星期
if (m == 1 || m == 2)
{
m += 12;
--y;
}
int w = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7;
return w + 1;
}
inline const int monthSToI(const string &monthS)
{
if (monthS == "January")
return 1;
else if (monthS == "February")
return 2;
else if (monthS == "March")
return 3;
else if (monthS == "April")
return 4;
else if (monthS == "May")
return 5;
else if (monthS == "June")
return 6;
else if (monthS == "July")
return 7;
else if (monthS == "August")
return 8;
else if (monthS == "September")
return 9;
else if (monthS == "October")
return 10;
else if (monthS == "November")
return 11;
else if (monthS == "December")
return 12;
else
return -1;
}
inline const string WeekIToS(const int &weekI)
{
switch (weekI)
{
case 1:
return "Monday";
case 2:
return "Tuesday";
case 3:
return "Wednesday";
case 4:
return "Thursday";
case 5:
return "Friday";
case 6:
return "Saturday";
case 7:
return "Sunday";
default:
return "ERROR!";
}
}
int main()
{
int day, year;
string month;
while (cin >> day >> month >> year)
{
int week = dateToWeekI(year, monthSToI(month), day);
cout << WeekIToS(week) << endl;
}
return 0;
}
Codeup 1931问题 C: 打印日期
#include <cstdio>
char month[13][2]={{0,0},{31,31},{28,29},{31,31},{30,30},{31,31},{30,30},{31,31},{31,31},{30,30},{31,31},{30,30},{31,31}};
bool isleap(int year) {
return (year%4==0 && year%100!=0) || (year%400==0);
}
int main() {
int y,n;
int month_num=0,month_sum=0;
while(scanf("%d %d", &y, &n)!=EOF) {
for(int i=1; i<13 && n>0; i++) {
n -= month[i][isleap(y)];
month_num=i;
}
n+=month[month_num][isleap(y)];
printf("%04d-%02d-%02d\n", y,month_num,n);
}
return 0;
}
Codeup 2026问题 D: 日期类
#include <cstdio>
int month[13][2]={{0,0},{31,31},{28,29},{31,31},{30,30},{31,31},{30,30},{31,31},{31,31},{30,30},{31,31},{30,30},{31,31}};
int main() {
int m;
scanf("%d", &m);
while(m--) {
int dd, mm, yy;
scanf("%d %d %d", &yy, &mm, &dd);
dd++;
if(dd==month[mm][0]+1) {
mm++;
dd=1;
}
if(mm==13) {
yy++;
mm=1;
}
printf("%04d-%02d-%02d\n", yy, mm, dd);
}
return 0;
}
Codeup2063 问题 E: 日期累加
#include <cstdio>
int month[13][2]={{0,0},{31,31},{28,29},{31,31},{30,30},{31,31},{30,30},{31,31},{31,31},{30,30},{31,31},{30,30},{31,31}};
bool isleap(int year) {
return (year%4==0 && year%100!=0) || (year%400==0);
}
int main() {
int dd, mm, yy, n;
int count;
scanf("%d", &n);
while(n--) {
scanf("%d %d %d %d", &yy, &mm, &dd, &count);
while(count--) {
dd++;
if(dd==month[mm][isleap(yy)]+1) {
mm++;
dd=1;
}
if(mm==13) {
yy++;
mm=1;
}
}
printf("%04d-%02d-%02d\n", yy, mm, dd);
}
return 0;
}
3.5进制转换
Codeup 1941问题 A: 又一版 A+B
#include <cstdio>
int main() {
long long a, b, c;
int m, num=0;
int z[40]={0};
scanf("%d", &m);
while(m!=0) {
scanf("%lld %lld", &a, &b);
c=a+b;
do{
z[num++]=c%m;
c=c/m;
}while(c!=0);
for(int i=num-1; i>=0; i--) {
printf("%d", z[i]);
}
printf("\n");
num=0;
scanf("%d", &m);
}
return 0;
}
Codeup 1942 问题 B: 数制转换
已通过OJ
#include <cstdio>
char digits[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
int main() {
int a, b;
char n[50];
int z[50], num[50];
while(scanf("%d %s %d", &a, &n, &b)!=EOF) {
//puts(n);
int k=0;
while(n[k]!='\0') { //将字母全部转化为数字
if(n[k]>='0' && n[k] <='9') {
num[k]=n[k]- '0';
k++;
}else if(n[k]>='A' && n[k]<='F') {
num[k]=n[k]-55;k++;
} else {
num[k]=n[k]-87;k++;
}
}
int length=k-1, sum=0; //sum用于保存n转化为10进制后的数字
for(int i=0; i<k; i++) {
int temp=1;
for(int j=0; j<k-1-i; j++) { //计算多次方项
temp*=a;
}
sum += num[i]*temp;
temp=1;
}
int number=0;
do{ //将sum转化为b进制数
z[number++]=sum%b;
sum=sum/b;
}while(sum!=0);
for(int q=number-1; q>=0; q--) {
if(z[q]<=9) {
printf("%d", z[q]);
}else if(z[q]>9 && z[q]<=16) {
printf("%c", digits[z[q]]);
}
}
printf("\n");
}
return 0;
}
Codeup 1943 问题 C: 进制转换
------------关于模拟短除法-----------------------------
题目已经说了数字可能超过30位数字,但自己写的时候由于不知道怎么写,所以是按照long long写的,因此无法通过OJ;
代码如下:
#include <cstdio>
int main() {
long long n; //n为输入的数据
while(scanf("%lld", &n)!=EOF) {
int z[200];
int num=0;
do{
z[num++]=n%2;
n=n/2;
}while(n!=0);
for(int i=num-1; i>=0; i--) {
printf("%d", z[i]);
}
printf("\n");
}
return 0;
}
因此必须考虑以字符串的形式接收数字,然后再模拟短除法来计算其二进制数
除二的过程:
for(int j=i; j<length; j++) {
int temp=number[j];
number[j] = (number[j]+c) / 2 ;
if(temp%2==1){
c = 10;
} else {
c = 0;
}
if(number[i] == 0){
i++;
}
}
如下为代码:
#include <cstdio>
int main() {
char str[32];
while(scanf("%s", str)!=EOF) {
int i=0, number[32]={0};
while(str[i]!='\0') { //将字符串转化为数字
number[i]= str[i]-'0';
i++;
}
int length=i; //表示数字的个数
int c=0, ans[200]={0};
int k=0;
i=0;
while(i<length) {
ans[k++]= number[length-1]%2;
c=0;
for(int j=i; j<length; j++) {
int temp=number[j];
number[j] = (number[j]+c) / 2 ;
if(temp%2==1){
c = 10;
} else {
c = 0;
}
if(number[i] == 0){
i++;
}
}
}
for(int m=k-1; m>=0; m--) {
printf("%d", ans[m]);
}
printf("\n");
}
return 0;
}
Codeup 1944问题 D: 八进制
#include <cstdio>
int main() {
int n;
while(scanf("%d", &n)!=EOF) {
int z[50], num=0;
do{
z[num++]=n%8;
n=n/8;
}while(n!=0);
for(int i=num-1; i>=0; i--) {
printf("%d", z[i]);
}
printf("\n");
}
return 0;
}
3.6字符串处理
Codeup 5901 问题 I: 【字符串】回文串
#include <cstdio>
#include <cstring>
int main() {
char str[256];
while(scanf("%s", str)!=EOF) {
int length=strlen(str);
int i;
for(i=0; i<length/2; i++) {
if(str[i]!=str[length-1-i]){
printf("NO\n");
break;
}
}
if(i==length/2) {
printf("YES\n");
}
}
return 0;
}
Codeup 1785 问题 A: 字符串连接
注意:两个给定的字符串是以空格分界的,因此使用scanf("%s %s", str1, str2)是不会有问题的。
由于是多点测试,因此printf要加上\n
#include <cstdio>
int main() {
char str1[110], str2[110];
while(scanf("%s %s", str1, str2)!=EOF){
printf("%s%s\n", str1, str2);
}
return 0;
}
Codeup 1805问题 B: 首字母大写
注意:a -= b+c 实际上是 a= a-(b+c) 即 a= a-b-c
#include <cstdio>
#include <cstring>
int main() {
char str[110];
while(gets(str)!=NULL) {
if(str[0]>='a' && str[0]<='z') {
str[0] -= 'a'-'A';
}
for(int i=1; i<strlen(str)-1; i++) {
if(str[i]==' ' || str[i]=='\t' || str[i]=='\r' || str[i]=='\n') {
if(str[i+1]>='a' && str[i+1]<='z') {
str[i+1] -= 'a'-'A';
}
}
}
puts(str);
}
return 0;
}
Codeup 1808 问题 C: 字符串的查找删除-❌
不知道问题在哪里,感觉自己没写错,且给定的例子也能正常通过,不知道哪个边界条件没考虑
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int isSame(char a, char b) { //1表示相同, 0表示不同
if(a==b) return 1;
else if(a>b && a>='a' && a<='z' && b>='A' && b<='Z') {
if(a-32==b) return 1;
} else if(a<b && a>='A' && a<='Z' && b>='a' && b<='z') {
if(a+32==b) return 1;
}
return 0;
}
int main() {
char str0[200];
cin.getline(str0, 200);
char str1[200]; //表示输入的待删除的数组
int k=0;
char str2[200]; //表示打印的数组
while(gets(str1)!=NULL) {
k=0;
for(int i=0; i<strlen(str1); i++) {
if(str1[i]==' ') continue;
else if(isSame(str1[i], str0[0])) { //如果str1中出现与str0的首字符相同的字符,则进入循环
int temp=i;
int j;
for(j=0; j<strlen(str0); j++, i++) {
if(!isSame(str0[j], str1[i])) {
break;
}
}
if(j==strlen(str0)) { //如果相同
i--;
} else { //如果不同
for(int m=temp; m<i; m++) { //表示把这段不等的字符放入待打印的数组中取
str2[k++]=str1[m];
}
}
} else {
str2[k++]=str1[i];
}
}
str2[k]='\0';
puts(str2);
}
return 0;
}
以下为正确代码:
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
int i,j;
char m[100];
char str1[1000][1000];
char str2[1000][1000];
gets(m);
int len1=strlen(m);
int num=0;
while(gets(str1[num++]))
for(j=0;j<len1;j++)//将m中的字符全部转化为小写
if(m[j]>='A'&&m[j]<='Z')
m[j]=m[j]-'A'+'a';
for(i=0;i<num-1;i++)
{
int len2=strlen(str1[i]);
for(j=0;j<len2;j++)//将str1中的字母全部转化为小写,存入str2中
{
if(str1[i][j]>='A'&&str1[i][j]<='Z')
str2[i][j]=str1[i][j]-'A'+'a';
else
str2[i][j]=str1[i][j];
}
int k;
for(j=0,k=0;j<len2;)
{
if(str2[i][j+k]==m[k])
{
k++;
if(k==len1)
{
j=j+k;
k=0;
}
}
else
{
if(str2[i][j]!=' ')
printf("%c",str1[i][j]);
j++;
k=0;
}
}
printf("\n");
}
return 0;
}
Codeup 1962 问题 D: 单词替换
遇到的问题:
1.关于如何在一个字符串中查找给定片段:
代码如下
//如果要执行相应的操作,把代码加在相应的位置即可
int k=0;
fro(int i=0 ;i<strlen(str1); ){
if(str1[i+k]==str2[k]){
k++;
if(k==strlen(str2){
//
i=i+k;
k=0;
}
} else {
//
i++;
k=0;
}
}
2.对于gets()输入字符串,时刻要注意需不需要getchar()吸收换行符!
已通过OJ
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int main() {
char s[110], a[110], b[110]; //分别表示初始字符串,待替换的字符串
while(gets(s)!=NULL) {
scanf("%s %s", a, b);
int lens=strlen(s), lena=strlen(a), lenb=strlen(b);
int i; //count用于判断S的片段是否与a完全一致
int k; //表示S中与a相同部分字符的起始位序
for(i=0,k=0;i<lens;) {
if(s[i+k]==a[k]) {
k++;
if(k==lena) {
printf("%s", b);
i=i+k;
k=0;
}
} else {
printf("%c", s[i]);
i++;
k=0;
}
}
printf("\n");
getchar();
}
return 0;
}
Codeup 1963 问题 E: 字符串去特定字符
已通过OJ
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int main() {
char s[30000], c;
while(gets(s)) {
scanf("%c", &c);
int lens=strlen(s);
for(int i=0; i<lens; i++) {
if(s[i]==c) {
continue;
} else {
printf("%c", s[i]);
}
}
printf("\n");
getchar();
}
return 0;
}
Codeup 1967 问题 F: 数组逆置
已通过OJ
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int main() {
char s[210];
while(gets(s)) {
int lens=strlen(s);
for(int i=lens-1; i>=0; i--) {
printf("%c", s[i]);
}
printf("\n");
}
return 0;
}
Codeup 2025 问题 G: 比较字符串
已通过OJ
#include <cstdio>
#include <cstring>
int main() {
int m;
scanf("%d", &m);
while(m--) {
char a[55], b[55];
scanf("%s %s", a, b);
if(strlen(a)>strlen(b)) {
printf("%s is longer than %s\n",a, b);
} else if(strlen(a)==strlen(b)) {
printf("%s is equal long to %s\n", a, b);
} else {
printf("%s is shorter than %s\n", a, b);
}
}
return 0;
}
Codeup 2064问题 H: 编排字符串
注意:1.题目要求最多输出四个字符串!如果忽视了这个,会显示输出超限
2.仔细审题!看清每行字符输出的变化,不要想当然!
已通过OJ
#include <cstdio>
#include <cstring>
int main() {
int m;
scanf("%d", &m);
char str[m][25];
for(int i=0; i<m ; i++) {
scanf("%s", str[i]);
int count=1;
int j;
for(j=i; j>=0 && count<=4; j--) {
printf("%d=%s", count, str[j]);
count++;
if(j>0) printf(" ");
}
printf("\n");
count=1;
}
return 0;
}