文章目录
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1051
解题思路1:
1.通过极坐标的形式进行复数相乘,如下图
2.对于特殊情况,比如A=-0.0001,如果直接保留2位小数,则为-0.00而非0.00,而这种情况,只针对A<0且A+0.005>0
3.对于B有三种情况,大于等于0是直接输出;与A类似的一种情况;B小于0并且B小于-0.005
参考代码:
#include <iostream>
#include <cmath>
using namespace std;
/*
解题思路:
*/
int main()
{
double r1, p1, r2, p2, A, B;
cin >> r1 >> p1 >> r2 >> p2;
A = r1 * r2 * cos(p1) * cos(p2) - r1 * r2 * sin(p1) * sin(p2);
B = r1 * r2 * cos(p1) * sin(p2) + r1 * r2 * sin(p1) * cos(p2);
if (A + 0.005 > 0 && A < 0)
printf("0.00");
else
printf("%.2f", A);
if(B >= 0)
printf("+%.2fi", B);
else if (B + 0.005 > 0 && B < 0)
printf("+0.00i");
else
printf("%.2fi", B);
return 0;
}
1052
解题思路:
1.将输入样例,转化为字符数组
2.按照要求输出
参考代码:
#include <iostream>
#include <vector>
using namespace std;
/*
解题思路:
*/
int main()
{
//
/*
1.定义一个字符串的二维数组v(有3行)
2.使用getline接受字符串
3.设置两个循环变量j,k分别表示[和]的位置
4.用双层while-if嵌套将表情放到row(row表示一行表情字符串)中,再将row放到v中
*/
vector<vector<string>> v;
for(int i=0; i<3; i++)
{
string s;
getline(cin,s);
vector<string> row; //定义一个字符数组
int j=0, k=0;
while(j < s.length())
{
if(s[j] == '[')
{
/*
k直接在此处自增是因为,如果第一次k走到]这个位置,if判断为真,压入栈,退出循环,其实
k已经走到下一个位置也就是下一个[处,如果将k放到if后面自增的话,那么k的值一直不变。
*/
while(k++ < s.length())
{
if(s[k] == ']')
{
row.push_back(s.substr(j+1, k-j-1));
break;
}
}
}
j++;
}
v.push_back(row);
}
int n;
cin >> n;
for(int i = 0; i < n; i++)
{
int a, b, c, d, e;
cin >> a >> b >> c >> d >> e;
/*
如果这里输入的数字,大于字符数组中字符元素的长度的话,输出Are you kidding me? @\/@,由于每个
字符串都是从1开始,所以如果输出0,也是选择的序号不存在,就输出Are you kidding me? @\/@
*/
if(a>v[0].size() || b>v[1].size() || c>v[2].size() || d>v[1].size() || e>v[0].size() || a<1 || b<1 || c<1 || d<1 || e<1)
{
cout << "Are you kidding me? @\\/@" << endl;
continue;
}
cout << v[0][a-1] << "(" << v[1][b-1] << v[2][c-1] << v[1][d-1] << ")" << v[0][e-1] << endl;
}
return 0;
}
知识总结:
1.用vector嵌套一个字符串数组
vector<vector<string>> v;
2.用getline接受一个字符串
getline(cin,s);
3.给字符串压栈
s.push_back(a); //将字符串a压栈到s中
4.截取字符串
s.substr(k,j); //表示在s字符串中,第k个位置,一共截取j个字符
1053
解题思路:
1.设置knkz,kz,
2.利用双层for比较:N,e,D,a 先比较电量是否高于观察期的一半,如果高于,则再判断是否大于指定的天数,计算
出knkz和kz的个数,最后再求百分比后输出
参考代码:
#include<iostream>
#include<cstdio>
using namespace std;
/*
解题思路:
*/
int main()
{
/*
注意事项:
1.对“可能控制”,“控制”的判断,先if判断是否存在超过一半的日子用电量低于某给定的阈值e,然后用一个
?:进一步判断是否观察期超过某给定阈值 D 天,然后选择是对knkz自增还是kz自增
2.输出%时,应该输出两个%
*/
int N,D,a;
double e,knkz=0.0,kz=0.0;
double temp=0.00;
cin >> N >> e >> D;
for(int i=0; i<N; i++)
{
cin >> a;
int tempcount=0;
for(int j=0; j<a; j++)
{
cin >> temp;
if(temp<e)
tempcount++;
}
if(tempcount>a/2)
{
a>D?kz++:knkz++;
}
}
printf("%.1f%% %.1f%%",knkz/N*100,kz/N*100);
return 0;
}
注意事项:
1.对“可能控制”,“控制”的判断,先if判断是否存在超过一半的日子用电量低于某给定的阈值e,然后用一个
?:进一步判断是否观察期超过某给定阈值 D 天,然后选择是对knkz自增还是kz自增
2.输出%时,应该输出两个%
1054
解题思路:
1.用字符数组来存放输入的值
2.不管a是啥,都将a转化为浮点型的数放到临时变量temp中
1.对于整数,实数而言,直接将字符类型转化为双精度浮点数
2.对于字母串而言,转化成的双精度浮点数是一个极小的数,比如aaa,转化为7.98855e-305
3.对于有多个小数点而言,只取到第2个小数点之前
3.在将temp保留2位小数,放到字符数组中,以a的长度为基准,遍历循环如果,a[i]!=b[i]则flag=1
4.如果flag=1或者temp<-1000 或者temp>1000,则输出:ERROR: aaa is not a legal number
5.否则累加temp,并记录个数
6.如果个数为1,则直接输出sum;如果个数为0,则输出undefined,否则输出:The average of 3 numbers is 1.38
参考代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int main()
{
char a[50],b[50];
double sum=0.0,temp=0.0;
int n,cnt=0;
cin >> n;
for(int i=0; i<n; i++)
{
scanf("%s",a);
sscanf(a,"%lf",&temp);
sprintf(b,"%.2f",temp);
int flag=0;
for(int j=0; j<strlen(a); j++) //对于字符数组而言,用strlen去求其长度
if(a[j]!=b[j])
flag=1;
if(flag || temp<-1000 || temp>1000)
{
cout << "ERROR: " << a << " is not a legal number" << endl;
continue;
}
else
{
sum+=temp;
cnt++;
}
}
//根据上面cnt的结果,输出对于字符串,而不是对于每个字符串都要输出平均值结果
if(cnt==1)
printf("The average of 1 number is %.2f\n",sum); //对于只有一个值时,直接输出sum,并且保留2位小数
else if(cnt>1)
printf("The average of %d numbers is %.2f\n", cnt, sum / cnt); //printf不能与endl结合
else
cout << "The average of 0 numbers is Undefined" << endl;
return 0;
}
注意事项:
1.后面的if-else是对于输出平均值的字符串,共3中情况:
1.只有1个值时,则直接输出sum,保留2位小数
2.没有值时,则直接输出The average of 0 numbers is Undefined
3.如果cnt>1则,输出sum/cnt,并保留2位小数即可
知识总结:
1.将字符数组a以浮点数的方式保存到temp中
sscanf(a, "%lf", &temp); //将a以浮点型的方式放到temp中
2.将temp变量以保留2位小数的方式输出到字符数组b中
char a[50], b[50];
sprintf(b, "%.2f",temp);
1055
解题思路1:
1.用结构数组来存储人名和身高
2.自定义一个cmp,如果身高不同的话,则按身高降序排列(对于输出是先输出最后一排,所以按照降序排列),身高相同按照名字的升序排列,对结构数组进行排序
3.设置两个边t,row分别表示:t表示结构数组中,按照n/k分配好的第一个下标,row表示行树,初值分别为0,k
4.如果row==k,则让m=n-n/k*(k-1)表示最后一行人数,如果row!=k,则m=n/k表示每行的人数
5.定义一个字符串数组ans,来存放人名。从按照n/k划分好的结构数组中将人名放到ans中,当然先一次性放完左边合适的人名,然后
再一次性放完右边合适的人名
6.按照输出要求输出这一排人名
7.不要忘记row–,t+=m
参考代码:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
/*
解题思路:
*/
//设置一个结构
struct node
{
string name;
int height;
};
//设置一个cmp,用:?来表示,如果身高不同的话,则按降序排列,身高相同按照名字的升序排列
int cmp(struct node a, struct node b)
{
return a.height != b.height ? a.height > b.height : a.name < b.name;
}
int main()
{
int n, k, m;
cin >> n >> k;
//用vector来定义一个结构数组
vector<node> stu(n);
for(int i = 0; i < n; i++)
{
cin >> stu[i].name;
cin >> stu[i].height;
}
sort(stu.begin(), stu.end(), cmp);
int t = 0, row = k;
while(row)
{
if(row == k) //对于最后一排而言,肯定要先输出,然后依次是n/k的个数,m表示每排的人数
{
m = n-n / k * (k - 1);
}
else
{
m = n / k;
}
//定义一个字符串数组,表示每排的人名
vector<string> ans(m);
//t初值是0,又因为结构数组,按照身高降序排列,名字升序排列,所以stu[t].name就表示身高在这排中最大的人名,ans[m/2]=stu[t].name就是把每排中身高最大的人放到中间
//t在样例中的值分别是0,4,7,t表示结构数组中,按照n/k分配的第一个下标
ans[m / 2] = stu[t].name;
// 左边⼀列
/*
1.j是人名字符串数组ans的变量,i是结构数组stu的变量
2.j=m/2-1,表示从紧靠中间的左边开始
3.对于for含义是一次直接将左边合适的人名全部输出,所以变量i是递增2
1.i=t+1; 表示从按照划分的结构数组中的第2个位置开始,都放在左边
*/
int j = m / 2 - 1;
for(int i = t + 1; i < t + m; i = i + 2)
ans[j--] = stu[i].name;
// 右边⼀列
/*
1.j=m/2+1; 表示从紧靠中间的右边开始
2.i从t+2开始,表示从按照划分的结构数组中的第3个位置开始,都放在右边
*/
j = m / 2 + 1;
for(int i = t + 2; i < t + m; i = i + 2)
ans[j++] = stu[i].name;
// 输出当前排
cout << ans[0];
for(int i = 1; i < m; i++)
cout << " " << ans[i];
cout << endl;
t = t + m;
row--;
}
return 0;
}
知识总结:
1.自定义cmp,对结构数组进行排序
struct node
{
string name;
int tall;
};
int cmp(node a,node b) //是对结构进行排序,所以必须定义两个结构node类型的变量a,b。函数类型还是int。如果身高不同按照降序排列,否则按照名字的升序排列
{
return a.tall!=b.tall?a.tall>b.tall:a.name<b.name;
}
int main()
{
int m,n,k;
cin >> n >> k;
vector<node> stu(n);
for(int i=0; i<n; i++)
cin >> stu[i].name >> stu[i].tall;
sort(stu.begin(),stu.end(),cmp);
}
1056
解题思路:
1.通过观察,可知sum+=a[i] * 11 * (n-1)
参考代码:
#include<iostream>
using namespace std;
int main(){
int n,sum=0;
cin >> n;
int a[n];
for(int i=0; i<n; i++){
cin >> a[i];
sum+=a[i]*11*(n-1);
}
cout << sum;
return 0;
}
1057
解题思路1:
1.先计算字符串中字母的所代表值的和
2.对其进行2进制计算,同时计算1,0的个数
参考代码1:
#include<iostream>
using namespace std;
/*
解题思路:
*/
int main()
{
string s;
getline(cin,s);
int sum=0,temp,ycount=0,lcount=0;
for(int i=0; i<s.size(); i++)
{
if('a'<=s[i] && s[i]<='z')
temp=s[i]-'a'+1;
else if('A'<=s[i] && s[i]<='Z')
temp=s[i]-'A'+1;
else
continue;
sum+=temp;
}
while(sum!=0)
{
if(sum%2)
ycount++;
else
lcount++;
sum/=2;
}
cout << lcount << " " << ycount;
return 0;
}
解题思路2:
1.用getline输入一个字符串
2.通过for循环,首先用isalpha判断是否为字母,若是,用toupper将字母改为大写字母,然后累加
3.统计n为2进制时,0和1的个数
参考代码2:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s;
getline(cin,s);
int n=0;
for(int i=0; i<s.length(); i++)
if(isalpha(s[i]))
{
s[i]=toupper(s[i]);
n+=(s[i]-'A'+1);
}
int cnt0=0,cnt1=0;
while(n!=0)
{
if(n%2==0)
cnt0++;
else
cnt1++;
n/=2;
}
cout << cnt0 << " " << cnt1;
return 0;
}
知识总结:
1.isalpha()判断ch是否为英文字母,若是英文字母返回非0(小写字母为2,大写字母为1)
2.toupper()函数是将小写字母转化为大写字母
1058
解题思路:
1.vector<set> right(m)表示标准答案的二维数组,vector total(m), wrongCnt(m);
分别表示每道题的满分情况,每道题错误次数
2.第一个双层for:输入题目的情况
1.外层for控制m个题的循环
2.内存for根据输入标准答案选项的个数,输入到二维数组right中
3.第二个三层for:输入学生的答题情况,以及输出每个学生的成绩
1.外层for控制n个人
2.内存for控制每个人答m个题的情况
3.最内层for根据(后的数字,往set类型的st中insert学生的具体答案
4.第3个for找出错得最多的题目的错误次数
5.if-else:
如果错误次数为0,输出too simple
否则循环遍历题目,如果本题的错误次数与max一致,则输出i+1表示题号
参考代码:
#include <cstdio>
#include <vector>
#include <set>
#include <iostream>
using namespace std;
/*
解题思路:
注意事项:
1.每道题的选项个数就是一个形同虚设的值,直接用temp保存,没有实际用处
2.特别注意第二个三层for中,scanf("\n")的使用
知识总结:
1.set类型的变量,只能用inset输入
*/
int main()
{
int n, m, temp, k;
cin >> n >> m;
vector<set<char>> right(m); //用二维数组存放正确选项
vector<int> total(m), wrongCnt(m); //用int数组存放满分
//输入题目的信息
for(int i = 0; i < m; i++)
{
cin >> total[i] >> temp >> k; //total表示满分,temp表示题目个数,k表示是正确选项个数
//输入正确选项
for(int j = 0; j < k; j++)
{
char c;
cin >> c;
right[i].insert(c); //想要往set中插入值,必须使用insert
}
}
//输入学生的答题情况
/*
2.为啥没(的输入?
仔细看41行中有没(
*/
for(int i = 0; i < n; i++)
{
int score = 0;
scanf("\n"); //为了避免下一次的scanf直接读取\n而结束,保证每次都等待键盘输入……,也可以写成getchar()
for(int j = 0; j < m; j++) //这里是输入每一行中答题内容
{
if(j != 0)
scanf(" "); //用法和scanf("\n"); 一个意思
scanf("(%d", &k); //输入每个括号内有多少个答案
set<char> st;
char c;
for(int l = 0; l < k; l++) //将每个括号中的答案放到set中
{
scanf(" %c", &c);
st.insert(c);
}
scanf(")"); //接受一个反括号
if(st == right[j]) //如果括号中的答案和题目信息中的答案匹配,则该题为满分
{
score += total[j];
}
else
{
wrongCnt[j]++; //如果答案不对,则记录该题错误的个数 记录每道题的错误个数
}
}
printf("%d\n", score);
}
int maxWrongCnt = 0; //设置一个最大变量
for(int i = 0; i < m; i++) //找出错得最多的题目的错误次数
{
if(wrongCnt[i] > maxWrongCnt)
{
maxWrongCnt = wrongCnt[i];
}
}
if(maxWrongCnt == 0 //如果错得最多的题目的错误次数为0,输出Too simple
printf("Too simple");
else //首先输出错得最多的题目的错误次数,如果本题的错误次数和maxWrongCnt一致,则输出i+1
{
printf("%d", maxWrongCnt);
for(int i = 0; i < m; i++)
{
if(wrongCnt[i] == maxWrongCnt)
{
printf(" %d", i + 1);
}
}
}
return 0;
}
知识总结:
1.关于scanf("\n")与scanf(" ")的讨论
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
int n,k=3;
cin >> n;
/*
此代码的含义是:
1.输入一个n,然后循环输入(k1 (k2 (k3 .... 并输出k1 k2 k3
*/
for(int i = 0; i < n; i++)
{
scanf("\n"); //吃掉上面那个输入n时的回车,加入此行代码,只针对于输入带有符号的输入
scanf("(%d", &k);
cout << k << endl;
}
return 0;
}
2.关于set类型的用法:
#include<iostream>
#include<set>
using namespace std;
int main()
{
set<int> s;
set<int>::iterator its; //设置一个迭代器
int temp,n;
cin >> n;
for(int i=0; i<n; i++) //只能以insert的方式插入数字
{
cin >> temp;
s.insert(temp);
}
for(its=s.begin(); its!=s.end(); its++) //使用迭代的方式读取数字
cout << *its;
return 0;
}
注意事项:
1.每道题的选项个数就是一个形同虚设的值,直接用temp保存,没有实际用处
2.特别注意第二个三层for中,scanf("\n")的使用
3.如果不加循环中scanf("\n")运行结果:
原因是:
在输入完n后,会敲一个回车,这个回车\n进入缓冲区,而scanf遇到(空格,制表符,回车)会自动结束,所以不理下面的scanf("(%d",&k),空白区中一直有\n,所以每次循环scanf一遇到\n就结束,则一直输出3。若加上scanf("\n"),则回车时将\n吃掉,所以重新正常输入,然后输出,在进入下一次循环时,scanf("\n")还是会吃掉上一次输入完后的\n
如果这样写,当max为0时,则输出完Too simple 后还要输出00000
所以一定要将for写入else中
1059
解题思路1:
1.设置一个数组ran,以学号为数组下标,以排名为数组元素
2.先输出学号,用printf,用%04d,占4位输出,不足为数左端补0
3.如果ran[id]==0表示id根不不在排名里,输出Are you kidding?
4.设置set类型的集合ss,ss保存的是id号,先在ss中寻找id是否存在,是,就输出checked 不是,就把数字插进去
5.如果ran[id]==1,输出Mystery Award
6.然后排名是素数,输出Minion
7.其余输出Chocolate
参考代码:
#include<iostream>
#include<set>
using namespace std;
bool sushu(int a)
{
if(a<=1)
return false;
for(int i=2; i<a; i++)
if(a%i==0)
return 0;
return 1;
}
int main()
{
int n;
cin >> n;
int ran[10000],id;
for(int i=0; i<n; i++)
{
cin >> id;
ran[id]=i+1;
}
int m;
cin >> m;
set<int> ss;
for(int i=0; i<m; i++)
{
cin >> id;
printf("%04d: ",id);
if(ran[id]==0)
{
cout << "Are you kidding?" << endl;
continue;
}
if(ss.find(id)==ss.end())
ss.insert(id);
else
{
cout << "Checked" << endl;
continue;
}
if(ran[id]==1)
cout << "Mystery Award" << endl;
else if(sushu(ran[id]))
cout << "Minion" << endl;
else
cout << "Chocolate" << endl;
}
return 0;
}
知识总结:
1.set中的find
if( ss.find(id) == ss.end() ) //表示ss中没有找到id这个值
1060
解题思路:
1.一般的思路肯定是,从骑行的最大公里开始,看是否有E天超过E公里,从大到小开始寻找
2.此题的思路是以E天为准,从1开始,将每天的骑行距离按照降序排列,从下标为1开始
3.a[p]>p:当p=1时,表示肯定有1天超过1公里;当p=2时,表示肯定有2天超过2公里;当p=3时,表示肯定有3天
超过3公里…一直循环到a[p]<=p此时就表示,当天的距离没有超过p,则E就是上一个值,也就是为啥ans表示E从0
开始,p从1开始,结果E就是ans
参考代码:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
int n;
cin >> n;
int a[n+1];
for(int i=1; i<=n; i++)
cin >> a[i];
sort(a+1,a+n+1,cmp);
int ans=0,p=1;
while(ans<=n && a[p]>p)
{
ans++;
p++;
}
cout << ans;
return 0;
}