例如:1024的五次方数为1+0+32+1024=1057
输入
无
输出
每个数独立一行输出
样例输入
无
样例输出
无
题解:
#include
#include //cmath是c++语言中的标准库头文件。\
其中的 “c” 表示其中的函数是来自 C标准库,\
“math”表示为数学常用库函数。\
包含了如下库函数\
std::pow(); //求幂函数\
std::exp(); //指数函数\
std::sqrt(); //平方根
//pow 函数用法示例:
//area = pow(4.0,2);=>(4.0)^2=16.0
using namespace std;
int main()
{
//话不多说,暴力枚举
//1024 => 1^+0^5+2^5+4^5=1057
//123 => 1^5+2^5+3^5=5+32+243=280
//521 => 5^5+2^5+1^5=3158
//由此可见: i<=sum
//当i>sum时,为临界状态,当超过临界之外,sum就不可能再追上i了
//i从2开始,是因为题目默认0和1不算入答案(出题人不够严谨)
for(int i=2;i<=999999;i++){
//(9^5)×1=59049(蓝桥杯可以随便使用电脑上的计算器)
//设位数为n,由题意得到 10^n <= 9^5 *n , 每次逐渐增加位数(n)推出 n最大为6.
//上下作对比:
//10^1 = 10 10^4=10000 10^5=100000 10^6=1000000
//9^5*1 = 59049 9^5*4=236196 9^5*5=295245 9^5*6=354294
//当n=6,达到6位数时,i>sum,所以临界定为999999
int sum = 0;
int t = i;
while(t>0){//将i进行拆分
sum += pow(t%10,5); // 取余,不断得到当前t的最低位,再5次方 , 再讲将其依次加起来
t /= 10;//取整
}
if(sum == i){//如果拆分之后,数的5次方和==i,就输出并换行!
cout<<i<<endl;
}
}
return 0;
}
/*
输出:
4150
4151
54748
92727
93084
194979
*/
输入
第一行为序列的大小N(1< =N< =1000)和操作个数M(1< =M< =1000)。
第二行包含N个数字,表示初始序列。
接下来M行,每行两个整数x,y (1< =x,y< =N),表示要交换的两个整数。在一次交换中,如果x和y相等,则不会改变序列的内容。
输出
输出N行,为交换后的序列中的数。
样例输入
5 2
1 2 3 4 5
1 2
3 4
样例输出
2
1
4
3
5
例如:样例输入是什么意思?N表示5个数,M=2表示输入完初始序列之后,
接下来的2行,每行两个整数x,y,分别表示要交换的两个整数。
题解:
#include //万能头文件#include 包含了,目前c++所包含的所有头文件!!!!
//#include相当于写了以下所有头文件
/*
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
/*void swap(int &a,int &b){ //swap函数可写可不写,因为头文件已经包含了此函数
int t;
t=a;
a=b;
b=t;
}*/
/*
* 本题还有一个 很重要的默认 条件:默认 您输入 的数是1,2,3,4,5,...这样有序的数,
* 且 要交换的数也是前两个一 换,紧接着, 两个一换,...
*/
int main(){
int a[1001],x[1001],y[1001];//定义三个 足够大的数组
int i,n,m;
scanf("%d %d",&n,&m);//输入n个数, m为要进行交换的行数
for(i=0;i<n;i++)//输入n个数, 存到a数组中
//0 1 2 3 4
//1 2 3 4 5
scanf("%d",&a[i]);
for(i=0;i<m;i++){//输入: 接下来的m行要交换
scanf("%d %d",&x[i],&y[i]);// 比如:样式输入的例子中,第0行要换,第1行要换
//x[i] y[i]
// 1 2
// 3 4
}
for(i=0;i<m;i++){
swap(a[x[i]-1],a[y[i]-1]);//x[0]是1,-1,=0 ; y[0]是2,-1,=1
//x[1]是3,-1,=2 ; y[1]是4, 1,=3
//刚好进行 交换
}
for(i=0;i<n;i++){
printf("%d\n",a[i]);
/*
*2
*1
*4
*3
*5
*/
}
}
题目描述:
给出一个整数 n 和 k 个变换规则。
规则:
一位数可变换成另一个一位数:
规则的右部不能为零。
例如:n=234。有规则(k=2):
2-> 5
3-> 6
上面的整数 234 经过变换后可能产生出的整数为(包括原数):
234
534
264
564
共 4 种不同的产生数
问题:
给出一个整数 n 和 k 个规则。
求出:
经过任意次的变换(0次或多次),能产生出多少个不同整数。
仅要求输出个数。
输入
n k
x1 y1
x2 y2
… …
xn yn
(n< 10^30)
(k< =15)
输出
一个整数(满足条件的个数)
样例输入
样例输出
题解:
#include
using namespace std;
int tag[10][10]={0};//tag[i][j]=1表示存在i->j的变换
int d[10];
int p[1000];
int main()
{
string a;//存储输入的整数
int n;//输入的变换规则的个数
while(cin>>a>>n)//输入目标数字 和 n个变换规则
{
int x,y;
for(int i=0;i<n;i++)// 循环n次,将n个规则依次输入
{
cin>>x>>y;//例如:样式输入2->5,3->6
tag[x][y]=1;//tag[2][5]=1 tag[3][6]=1
}
/**
*如果存在i->k,k->j ,则通过递推 从i->j 的变换也存在
*/
for(int k=1;k<10;k++)//1--->2,2-->3故1--->3可以利用佛洛依德算法进行实现
for(int i=0;i<10;i++)
for(int j=1;j<10;j++)
if(tag[i][k]&&tag[k][j])//k 与 j 对称
tag[i][j]=1;
//计算每个数字的变换次数
for(int i=0;i<10;i++)
{
tag[i][i]=1;
for(int j=0;j<10;j++)
if(tag[i][j])
d[i]++;//d[i]表示数字i存在的变换数量
}
int z=0;
p[0]=1;//每个数字至少有一种形态,就是他本身,235
for(int i=0;a[i];i++)
{
z=0;
int x=d[a[i]-'0'];//数字字符与字符‘0’的ASCII差值等于数字的值
//输入整数的每一位的形态个数的乘积就是这个整数的形态个数(参考数学排列组合Ann)
for(int i=0;i<500;i++)
{
p[i]=(p[i]*x+z);//乘法运算,z是进位数
z=p[i]/10;
p[i]%=10;
}
}
int i=500;
while(p[i]==0) i--;//计算出p数组有多长有效位,即,结果的整数值有多少位
for(;i>=0;i--)//将结果从高位到低位,输出每一位的数字,组成结果这个整数
{
cout<<p[i];
}
cout<<endl;
break;
}
}
注意:短线“-”个数要与题目中一致,否则系统会判为错误。
输入
年月和月份
输出
无
样例输入
2010 9
样例输出
1 2 3 4
题解:
#include
using namespace std;
//判断是否为闰年=>能被400整除,或者能被4整除但不能被100整除才是闰年。
bool isleap(int num){
if(num % 400 == 0){//可被400整除为闰年
return true;
}else if(num % 4 == 0 && num % 100 != 0){//若被4整除但不能被100整除也是闰年
return true;
}else{//前边两个条件,满足其一就是闰年,都不满足就是平年
return false;
}
}
//判断某年某月有多少天
int mouthinday(int year, int mouth){
if(mouth == 1 || mouth == 3 || mouth == 5 || mouth == 7 || mouth == 8 || mouth == 10 || mouth == 12){
return 31;//一三五七八十腊,三十一天永不差
}else if(mouth == 4 || mouth == 6 || mouth == 9 || mouth == 11){
return 30;
}else if(mouth == 2){
if(isleap(year)){
return 29;//不是闰月29天
}else{
return 28;//是闰月28天
}
}
}
//计算从2007.1到输入年月的 前一个月的天数 =>即算出从2007.1到输入的某年某月之间一共隔了多少天
int cntday(int year, int mouth){//2022 1
int day = 0;
for(int i = 2007; i <= year; i++){//i<2022 ,i++
for(int j = 1; j <= 12; j++){
if(i == year && j == mouth){//i==2022且j==1 =>j是从1开始的,\
mouth可能是1~12任意一个数,\
所以j只能小于或等于mouth,\
当j==mouth为临界条件,\
这时候就可以return day,退出函数了
return day;
}
day += mouthinday(i, j);//不退出就一直加
}
}
}
int main(){
int year, mouth;
cin >> year >> mouth;//假设输入2022年1月
if(year < 2007){//如果输入年数小于2007直接return 0,这题没法算
return 0;
} else{
int day = cntday(year, mouth);//获取从2007年1月到2022年1月有几天
int week = day % 7 + 1;//把2022年1月的天数取模,判断2020年1月1日是星期几
int num = mouthinday(year, mouth);//获取2022年1月有多少天
cout << "---------------------" << endl;
cout << " Su Mo Tu We Th Fr Sa" << endl;
cout << "---------------------" << endl;
//==========================================================
//样例输出最前面为空,故+1(i < 3 * mod + 1),如下图所示:
/*
2022 1
---------------------
Su Mo Tu We Th Fr Sa
---------------------
1//第1行
2 3 4 5 6 7 8//第2行
9 10 11 12 13 14 15//第3行
16 17 18 19 20 21 22//第4行
23 24 25 26 27 28 29//第5行
30 31 //第6行
---------------------
*/
for(int i = 0; i < 3 * week + 1; i++){ //这个for循环输出的是 第1行要输出几个空格
printf(" "); //根据前面判断的星期数,打印空格,\
如:星期6要打19个空格=3*6+1\
星期1要打个4空格=3*1+1\
...\
一开始占一个,从星期n到星期n+1要3个空格
}
//===========================================================
for(int i = 1; i <= num; i++){//从第一天循环到最后一天
if(week == 7){//每次week指到星期日时就换行
week = 0;//重置星期数 =>即星期一到星期日用1 2 3 4 5 6 0表示
printf("\n");
printf(" ");//第一列为空,这里打印一个空格
}
printf("%2d ", i);//C语言的占位打印,占两位
week++; //每打印一个数,week指针加1,指向下一个位置
}
cout << "\n---------------------" << endl;
}
return 0;
}
输入
利润
输出
应发奖金总数,保留两位小数
样例输入
210000
样例输出
18000.00
题解:
#include
int main(){
double a;
scanf("%lf",&a);
if(a<=100000)printf("%.2f",a*0.1);//利润低于或等于10万元时,奖金可提10%;
else if(a<=200000)printf("%.2f",10000+(a-100000)*0.075);//利润高于10万元,低于20万时,\
低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%
else if(a<=400000)printf("%.2f",17500+(a-200000)*0.05);//20万到40万之间时,高于20万元的部分,可提成5%
else if(a<=600000)printf("%.2f",27500+(a-400000)*0.03);//40万元到60万元 之间时高于40万元的部分,可提成3%
else if(a<=1000000)printf("%.2f",33500+(a-600000)*0.015);//60万到100万之间时,高于60万元的部分,可提成1.5%
else printf("%.2f",39500+(a-1000000)*0.01);//高于100万元时,超过100万元的部分按1%提成。
return 0;
}
输入
两行。
第一行一个整数n,表示要对多少个数据
第二行有n个整数,中间用空格分隔。表示n个数据。
数据规模和约定
10< =n< =200,各个整数不超出整型范围
输出
一行,按从大到小排列的前10个数据,每个数据之间用一个空格隔开。
样例输入
26
54 27 87 16 63 40 40 22 61 6 57 70 0 42 11 50 13 5 56 7 8 86 56 91 68 59
样例输出
91 87 86 70 68 63 61 59 57 56
题解:
#include
//补充:#include:algorithm意为"算法",\
是C++的标准模版库(STL)中最重要的头文件之一,\
提供了大量基于迭代器的非成员模版函数。
using namespace std;
//自定义函数
bool cmp(int a,int b){
return a>b;//a>b 为真,从大到小降序排列
}
int main()
{
int n;//输入n个数
cin>>n;
int a[n];
int i;
for(i=0;i<n;i++)
{
cin>>a[i];// 将这个n个数放到 数组a[n]中
}
//sort(a,a+n,greater()); //将a[n]降序排列,a代表从哪开始排序,\
a+n表示排到那个元素,\
greater()表示从大到小排序[注:greater是大的意思]\
如果不写greater(),就默认从小到大排序
//如果比赛时忘了greater()怎么写,那么我们可以自写排序规则,如下:
sort(a,a+n,cmp);
for(i=0;i<10;i++)
{
cout<<a[i]<<" ";// 输出前10名
}
return 0;
}
输入
无
输出
每行为一组勾股数,用空格隔开
样例输入
无
样例输出
3 4 5
5 12 13
6 8 10
题解:
#include
int main(){//最好的题解
int a,b,c;
for(a=3;a<1000;a++){
for(b=a;b<1000;b++){
for(c=b;c<1000;c++){
if((a*a+b*b==c*c)&&(a+b+c<=1000)) printf("%d %d %d\n",a,b,c);
}
}
}
}
输入
输入一个字符串(长度不超过80),由若干个单词组成,单词之间用一个空格隔开。
输出
输出一个整数,即单词的个数。
样例输入
this is a book
样例输出
4
题解:
#include
//题目以空格为分隔符
int main()
{
char s[101]; //定义字符串数组
gets(s); //在s中输入字符串
int answer; //单词数
if(s[0] == '\0') answer=0;//第一个位置是空字符,则单词数为0
else answer=1;//第一个位置不是空字符,则单词数至少为1
for (int i = 0; s[i] != '\0'; i++) //循环遍历字符串
{
if (s[i] == ' ') //遇到空格,说明刚遍历完一个单词,单词数answer加一
answer++;
}
printf("%d\n", answer);
return 0;
}
X | X | X
---+---+---
| |
---+---+---
O | O | O
输入
无
输出
无
样例输入
无
样例输出
X | X | X
---+---+---
| |
---+---+---
O | O | O
注意:本题请同学们严格按照图形的格式输出,对齐,其中X和O为大写,否则系统会判为错误。
题解:
#include
using namespace std;
int main()
{
cout<<" X | X | X "<<endl;
cout<<"---+---+---"<<endl;
cout<<" | | "<<endl;
cout<<"---+---+---"<<endl;
cout<<" O | O | O "<<endl;
return 0;
}
输入
第一行是成绩的个数 n
第二行是学生的成绩,若干0~100的正整数,用空格隔开
输出
第一行为5个正整数,分别表示A,B,C,D,E五个等级段的人数
第二行一个正整数,表示人数最多的等级段中人数
接下来一行若干个用空格隔开的正整数,表示人数最多的那个等级中所有人的分数,按从大到小的顺序输出。
样例输入
10
100 80 85 77 55 61 82 90 71 60
样例输出
2 3 2 2 1
3
85 82 80
题解:
#include
using namespace std;
vector<int> A, B, C, D, E;//五个向量/动态数组
vector<int> f(vector<int> a, vector<int> b) {//返回a向量与b向量中, 元素最多的一个
if (a.size() > b.size())
return a;
else
return b;
}
int main(void) {
int n, digit;
cin >> n;//输入几个数=>n个
for (int i = 0; i < n; i++) {
cin >> digit;//依次将n个数输入
if (digit <= 100 && digit >= 90)//输入的数属于那个区间,就将其放到那个区间
A.push_back(digit);
else if (digit <= 89 && digit >= 80)
B.push_back(digit);
else if (digit <= 79 && digit >= 70)
C.push_back(digit);
else if (digit <= 69 && digit >= 60)
D.push_back(digit);
else
E.push_back(digit);
}
//输出每个分数段的人数
cout << A.size() << ' ' << B.size() << ' '<< C.size() << ' ' << D.size() << ' '<< E.size() << endl;
vector<int> G = f(f(f(f(A, B), C), D), E);
cout << G.size() << endl;
//list(双向链表)中排序的用法:ee.sort();
sort(G.begin(),G.end());//从小到大排序
while (!G.empty()) {
cout << G.back() << ' ';// 不断输出向量G最后一个元素
G.pop_back();//每输出一个,就从矢量G的末尾删除一个元素
}
return 0;
}