目录
洛谷p1055 ISBN号码
题目描述
每一本正式出版的图书都有一个 ISBN 号码与之对应,ISBN 码包括 9 位数字、1 位识别码和 3 位分隔符,其规定格式如 x-xxx-xxxxx-x
,其中符号 -
就是分隔符(键盘上的减号),最后一位是识别码,例如 0-670-82162-4
就是一个标准的 ISBN 码。ISBN 码的首位数字表示书籍的出版语言,例如 0 代表英语;第一个分隔符 -
之后的三位数字代表出版社,例如 670670 代表维京出版社;第二个分隔符后的五位数字代表该书在该出版社的编号;最后一位为识别码。
识别码的计算方法如下:
首位数字乘以 1加上次位数字乘以 2 ……以此类推,用所得的结果 mod11,所得的余数即为识别码,如果余数为 10,则识别码为大写字母 X。例如 ISBN 号码 0-670-82162-4
中的识别码 4 是这样得到的:对 067082162
这 9 个数字,从左至右,分别乘以 1,2,…,9 再求和,即 0×1+6×2+……+2×9=158然后取158mod11 的结果 4 作为识别码。
你的任务是编写程序判断输入的 ISBN 号码中识别码是否正确,如果正确,则仅输出 Right
;如果错误,则输出你认为是正确的 ISBN 号码。
输入格式
一个字符序列,表示一本书的 ISBN 号码(保证输入符合 ISBN 号码的格式要求)。
输出格式
一行,假如输入的 ISBN 号码的识别码正确,那么输出 Right
,否则,按照规定的格式,输出正确的 ISBN 号码(包括分隔符 -
)。
输入输出样例
输入 #1复制
0-670-82162-4
输出 #1复制
Right
输入 #2复制
0-670-82162-0
输出 #2复制
0-670-82162-4
说明/提示
2008 普及组第一题
题目分析
根据题意得出这个题目需注意以下几点
1.整个输入的字符串的长度只有13,判断识别码只需要特判字符串中最后一个字符
2.当取余时余数为10则识别码会特判为大写字母X
3.当模11后的识别码不等于所输入字符串的最后一个字符,则把识别码赋值给最后一个字符,然后输出新字符串,如果等于,则输出Right
代码示例
#include<bits/stdc++.h>
using namespace std;
char a[15];
int sum,j=1,k;
char c;
int main()
{
scanf("%s",a);
for(int i=0; i<12; i++)//循环累加求总和,如果遇到‘-’则i++
{ if(a[i]=='-')continue;
if(a[i]>='0'&&a[i]<='9')sum+=(a[i]-'0')*j++;
}
k=sum%11;
if(k==10)c='X';//特判当余数为10的时候
else c=k+'0';//数字转字符以便能存入字符串
if(a[12]!=c)//不相等的话赋值给a【12】
{
a[12]=c;
printf("%s",a);
}
else printf("Right");
}
洛谷p2404 自然数的拆分
题目描述
任何一个大于 1 的自然数 n,总可以拆分成若干个小于 n 的自然数之和。现在给你一个自然数 n,要求你求出 n 的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。然后你需要输出这些序列,其中字典序小的序列需要优先输出。
输入格式
输入:待拆分的自然数 n。
输出格式
输出:若干数的加法式子。
输入输出样例
输入 #1复制
7
输出 #1复制
1+1+1+1+1+1+1 1+1+1+1+1+2 1+1+1+1+3 1+1+1+2+2 1+1+1+4 1+1+2+3 1+1+5 1+2+2+2 1+2+4 1+3+3 1+6 2+2+3 2+5 3+4
说明/提示
数据保证,2≤n≤8。
题目分析
1.题目要求我们把一个自然数n拆分成若干个小于n的自然数之和,由题目输入输出示例可以得出是从1开始找并相加,如果找到的数不符合相加等于自然数n,则回退一步加1再找(这就可以得出dfs算法的运用)
2.举个案例4,4的话从1开始找,1+1+1+1,满足条件,所以把这几个数存入答案数组中输出,第二步就是如果第四个1接着往后面找变成1+1+1+2,此时不满足条件,进行回溯,回到上一步继续循环到1+1+1+3,此时也不满足条件,所以对于第四个1循环判断结束,此时回溯到第三个1变成1+1+2,此时满足条件,存入答案数组并准备输出,接着判断后面1+1+3,也满足条件所以存入数组输出,然后循环判断条件结束回溯到第二个1,第二个1开始变化,就会变成1+2,(后面加的数必须大于或等于前一个数)此时不满足条件,回溯到第一个1就会得出2+2;
代码示例
#include<bits/stdc++.h>
using namespace std;
int ans[1101],n;
void print(int cnt){//把每个满足条件的存进来的数组输出
cout<<ans[0];
for(int i=1;i<cnt;i++){
cout<<'+'<<ans[i];
}
cout<<endl;
}
void dfs(int pos,int cnt,int sum)//pos是代表从他开始往后找(这是从1开始往后找,找到最后一个1后开始回溯)
{
if(sum==n)//如果累加的值1等于n自然数的值则返回
{
print(cnt);
return;
}
if(sum>n)return;
for(int i=pos; i<n; i++)//
{
ans[cnt]=i;
dfs(i,cnt+1,sum+i);//dfs(从i开始找,数组存放的下标,每次加起来的和)
}
}
int main(){
cin>>n;
dfs(1,0,0);
}
如上面有误,还请大佬指教一二