文章目录
-
- 1001.A+B
- 1005.拼写正确
- 1006.签到与签出
- 1035.密码
- 1036 .男孩VS女孩
- 1050.字符串减法
- 1071.说话方式
- 1061.约会
- 1016.电话账单 **(结构体排序)
- 1017.银行排队
- 1026.乒乓球 **(结构体排序)
- 1060.他们是否相等 **
- 1073.科学计数法??
- 1077.Kuchiguse
- 1082.中文读数字 **
- 1084.坏掉的键盘
- 1108.求平均值
- 1124.微博转发抽奖
- 1141.PAT单位排行 ** (结构体排序--多关键字比较)
- 1153. 解码PAT准考证(pair排序)
1001.A+B
- 题目意思是让我们输出a+b的值,并且输出格式是每三位加一个逗号
- 首先将a+b=c 转字符串(to_string ),然后用res存储新串,从后向前遍历,每有三位并且前面一位不是‘-’号就添加一位逗号
#include
#include
using namespace std;
int main(){
int a,b;
cin>>a>>b;
int c=a+b;
string num=to_string (c);
string res;
for(int i=num.size()-1,j=0;i>=0;i--){
res=num[i]+res;
j++;
if(j%3==0 && i && num[i-1]!='-')res=","+res;
}
cout<<res;
}
1005.拼写正确
- 题目要求我们计算输入数字每一位的总和,最后输出总和的每一位英文字母
- 数字范围过大直接用string读入再转数字计算总和,最后用二维数组映射方式存储每一位数字对应的英文单词
#include
#include
#include
using namespace std;
int main(){
string s;
cin>>s;
int res=0;
for(auto c:s)res+=c-'0';
char word[10][10] = {
"zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine",
};
s=to_string (res);
cout<<word[s[0]-'0']<<" ";
int len=s.size();
for(int i=1;i<len;i++){
cout<<""<<word[s[i]-'0'];
}
}
1006.签到与签出
- 注意:cin以空格作为间断分批读入字符串
- 两时间串长度相同,其大小服从字典序,直接比较即可
#include
#include
#include
using namespace std;
int main(){
int n;
cin>>n;
string oid,oti;
string cid,cti;
for(int i=0;i<n;i++){
string id,eti,lti;
cin>>id>>eti>>lti;
if(!i||eti<oti){
oid=id;
oti=eti;
}
if(!i||cti<lti){
cid=id;
cti=lti;
}
}
cout<<oid<<" "<<cid;
}
1035.密码
#include
#include
using namespace std;
const int N=1010;
string x[N];
int modify(string & s){
string og=s;
int len=s.size();
int i=0;
while(s[i]!=' ')i++;
for(i=i+1;i<len;i++){
if(s[i]=='1')s[i]='@';
if(s[i]=='0')s[i]='%';
if(s[i]=='l')s[i]='L';
if(s[i]=='O')s[i]='o';
}
if(s==og)return 0;
else return 1;
}
int main(){
int n;
int idx=0;
cin>>n;
while(n--){
string id,anw;
cin>>id>>anw;
if(modify(anw))x[idx++]=id+" "+anw;
}
if(!idx){
if(n==1)cout<<"There is 1 account and no account is modified";
else cout<<"There are "<<n<<" accounts and no account is modified";
}
else {
cout<<idx<<endl;
for(int i=0;i<idx;i++){
cout<<x[i]<<endl;
}
}
}
1036 .男孩VS女孩
- 题目是打印成绩最好的女孩和最差的男孩成绩和成绩之差,没有则输出Absent
#include
#include
#include
using namespace std;
const int N=110;
int posm,posf;
string name[N],sex[N],id[N],score[N];
int to_int(string s){
int len=s.size();
int res=0;
for(int i=0;i<len;i++){
res=res*10+s[i]-'0';
}
return res;
}
int main(){
int n;
int idx=0;
cin>>n;
int max=-1e9,min=1e9;
while(n--){
cin>>name[idx]>>sex[idx]>>id[idx]>>score[idx];
int grade=to_int(score[idx]);
if(sex[idx]=="F"&& grade>max)max=grade,posf=idx;
if(sex[idx]=="M"&& grade<min)min=grade,posm=idx;
idx++;
}
bool flag=false;
if(max==-1e9){
cout<<"Absent"<<endl;
flag=true;
}
else cout<<name[posf]<<" "<<id[posf]<<" "<<endl;
if(min==1e9){
cout<<"Absent"<<endl;
flag=true;
}
else cout<<name[posm]<<" "<<id[posm]<<" "<<endl;
if(flag)cout<<"NA";
else cout<<abs(to_int(score[posf])-to_int(score[posm]));
return 0;
}
1050.字符串减法
- 题目原意是找到字符串2中所有出现的过的字母在字符串1中删除
- 两重循环
O(n^2)
=10^8超时,所以直接使用哈希表优化代码
#include
#include
#include
using namespace std;
int main(){
string s1,s2;
getline(cin,s1);
getline(cin,s2);
int len1=s1.size(),len2=s2.size();
map<char,int> has;
for(int i=0;i<len2;i++)has[s2[i]]++;
string res;
for(int i=0;i<len1;i++)if(!has.count(s1[i]))res+=s1[i];
cout<<res;
}
1071.说话方式
- 本题统计次数最多的常用语,且不包含字母和数字以外的所有单词,不区分大小写
- 题目难点在于如何抠出每一个单词,可以采用类似
双指针+substr(i,j)
的方式读入每个字符串
#include
#include
#include
using namespace std;
int main(){
map<string,int> has;
string s;
getline(cin,s);
int len=s.size();
string cur;
for(int i=0;i<len;i++){
if(s[i]>='A'&&s[i]<='Z')s[i]+=32;
if((s[i]>='0'&&s[i]<='9')||(s[i]>='a'&& s[i]<='z')){
cur+=s[i];
}
else if(cur.size()) {
has[cur]++;
cur="";
}
}
if(cur.size())has[cur]++;
int max=0;
string res;
for(auto x :has){
if(x.second>max){
max=x.second;
res=x.first;
}
}
cout<<res<<" "<<max;
}
#include
#include
#include
using namespace std;
bool check(char c){
if(c>='a'&&c<='z'||c>='A'&&c<='Z'||c>='0'&&c<='9')return true;
else return false;
}
int main(){
map <string,int> has;
string s;
getline(cin,s);
int len=s.size();
for(int i=0;i<len;i++){
string cur;
if(check(s[i])){
int j=i;
while(j<len&& check(s[j]))cur+=tolower(s[j++]);
has[cur]++;
i=j;
}
}
int max=0;
string res;
for(auto x :has){
if(x.second>max){
max=x.second;
res=x.first;
}
}
cout<<res<<" "<<max;
}
1061.约会
#include
#include
using namespace std;
int main(){
string has[7]={
"MON","TUE","WED","THU","FRI","SAT","SUN"};
string time[14]={
"10","11","12","13","14","15","16","17","18","19","20","21","22","23"};
string s1,s2,c1,c2;
cin>>s1>>s2>>c1>>c2;
int len=s1.size();
int len2=c1.size();
bool flag =false;
for(int i=0;i<len;i++){
if(flag && (s1[i]>='0'&& s1[i]<='9' || s1[i]>='A'&&s1[i]<='N') && s1[i]==s2[i]){
if(s1[i]>='0'&&s1[i]<='9')cout<<0<<s1[i]<<":";
else cout<<time[s1[i]-'A']<<":";
break;
}
if(!flag && s1[i]>='A'&&s1[i]<='G' &&s1[i]==s2[i]){
cout<<has[s1[i]-'A']<<" ";
flag =true;
}
}
for(int i =0;i<len2;i++){
if(c1[i]>='A'&& (c1[i]<='Z' ||c1[i]>='a'&& c1[i]<='z') &&c1[i]==c2[i]){
if(i<10)cout<<'0'<<i;
else cout<<i;
break;
}
}
}
#include
#include
using namespace std;
int main()
{
string a, b, c, d;
cin >> a >> b >> c >> d;
int k = 0;
while (true)
{
if (a[k] == b[k] && a[k] >= 'A' && a[k] <= 'G') break;
k ++ ;
}
char weekdays[7][4] = {
"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
printf("%s ", weekdays[a[k] - 'A']);
k ++ ;
while (true)
{
if (a[k] == b[k] && (a[k] >= '0' && a[k] <= '9' || a[k] >= 'A' && a[k] <= 'N')) break;
k ++ ;
}
printf("%02d:", a[k] <= '9' ? a[k] - '0' : a[k] - 'A' + 10);
for (int i = 0;; i ++ )
if (c[i] == d[i] && (c[i] >= 'a' && c[i] <= 'z' || c[i] >= 'A' && c[i] <= 'Z'))
{
printf("%02d\n", i);
break;
}
return 0;
}
作者:yxc
链接:https://www.acwing.com/activity/content/code/content/262678/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
1016.电话账单 **(结构体排序)
- 这题英文版是真的看不懂…
- 简而言之就是算话费,输出每个人的通话时长,其通话时长先按照
时间排序
然后每个online和offline配对
之后就是打通和挂断的时间,其中多余的online和offline删除
,
- 计算话费:按照第一行的24小时段的话费计算,单位是
美分/分钟
- 本题的难点在于数据的存储以及话费的计算
- 由于每一个用户个人信息较多并且会考虑到时间排序,并且最后要按找字典序名称输出
自然想到用map存储客户姓名
以及结构体
存储对应数据,并且增加结构体内部排序,(为了方便对时间的排序及操作,直接改用相对于该月1号0:0点的时间存储时间)
- 话费的计算:
- 考虑到24个小时每个时间段话费均不同,不可能逐个计算话费,所以提前处理出
前缀和数组
#include
#include
#include
#include
#include
using namespace std;
const int N=1010,M=31*24*60+10;
int n;
int cost[24];
double sum[M];
struct record{
int minutes;
string state;
string format_time;
bool operator < (const record &t)const {
return minutes<t.minutes;
}
};
map<string,vector<record>> has;
int main(){
for(int i=0;i<24;i++)cin>>cost[i];
cin>>n;
for(int i=1;i<M;i++)sum[i]=sum[i-1]+cost[(i-1) %1440 /60]/100.0;
char name [25],format_time[20],state[10];
int month,date,hour,minute;
for(int i=0;i<n;i++){
scanf("%s %d:%d:%d:%d %s",name,&month,&date,&hour,&minute,state);
sprintf(format_time,"%02d:%02d:%02d",date,hour,minute);
int minutes=(date-1)*1440+hour*60+minute;
has[name].push_back({
minutes,state,format_time});
}
for(auto &p: has){
auto name =p.first;
auto record=p.second;
int len =record.size();
sort(record.begin(),record.end());
double total=0;
for(int i=0;i+1<len;i++){
auto a=record[i],b=record[i+1];
if(a.state=="on-line"&& b.state=="off-line"){
if(!total)printf("%s %02d\n",name.c_str(),month);
double payment=sum[b.minutes]-sum[a.minutes];
cout<<a.format_time<<" "<<b.format_time<<' '<<b.minutes-a.minutes<<" "<<"$";
printf("%.2lf\n",payment);
total+=payment;
}
}
if(total)printf("Total amount: $%.2lf\n",total);
}
}
1017.银行排队
- 题意是统计所有被服务客户的等待时间
- 和上一题处理时间的方式类似,唯一的不同是对于服务窗口的处理,可以看出唯一需要使用的就是当前结束时间最早的服务窗口,自然联想到可以用小根堆
priority_queue
处理
#include
#include
#include
#include
#include
#include
using namespace std;
const int N=1010;
map<int,int> has;
int main(){
int n,k;
cin>>n>>k;
int hour,minute,second,p;
for(int i=0;i<n;i++){
scanf("%d:%d:%d %d",&hour,&minute,&second,&p);
int times=hour*60*60+minute*60+second;
p=min(p,60);
has[times]=p*60;
}
priority_queue<int,vector<int>,greater<int>> q;
for(int i=0;i<k;i++)q.push(8*60*60);
int sum=0,cnt=0;
for(auto it:has){
int arrtime=it.first;
int protime=it.second;
if(arrtime>17*60*60)break;
int eartime=q.top();
q.pop();
int start_time=max(eartime,arrtime);
sum+=start_time-arrtime;
q.push(start_time+protime);
cnt++;
}
printf("%.1lf",(double)sum/cnt/60);
}
1026.乒乓球 **(结构体排序)
- 题意不做赘述,本题难点在于既有vip球桌又有vip会员,在存储数据时我们选择
普通和vip分开存储
,也就是分为普通会员,vip会员,普通球桌,vip球桌四种情况
来存储,而从题意上来看,我们每次只会用到最早到的普通会员,vip会员以及最早空闲的普通球桌,vip球桌,所以使用四个小根堆
来存储数据
情况1:空余球台比人多
- 对于
来的第一对同学
,如果是普通人则分普通球台,如果是vip则分VIP球台
情况2:排队人比球台多
- 对于
第一个闲下来的球台
,如果是普通球台,则分配给排队的第一对同学,如果是VIP球台,则分配给队伍中的vip.
#include
#include
#include
#include
#include
#include
using namespace std;
const int N=10010,M=110,INF=1000000;
int n,k,m;
struct persons{
int arrtime,playtime,start_time,waitting_time;
bool operator< (const persons &t)const{
if(start_time!=t.start_time)return start_time<t.start_time;
else return arrtime<t.arrtime;
}
bool operator> (const persons &t)const{
return arrtime>t.arrtime;
}
};
bool is_vip_table[M];
int table_cnt[M];
vector <persons> person;
struct tables{
int id;
int end_time;
bool operator> (const tables &t)const{
if(end_time!=t.end_time)return end_time>t.end_time;
else return id>t.id;
}
};
void assign(priority_queue<persons,vector<persons>,greater<persons>> &ps,priority_queue<tables,vector<tables>,greater<tables>> &ts){
auto p=ps.top();auto t=ts.top();
ps.pop(),ts.pop();
p.waitting_time=round((t.end_time-p.arrtime)/60.0);
p.start_time=t.end_time;
table_cnt[t.id]++;
person.push_back(p);
ts.push({
t.id,t.end_time+p.playtime});
}
string get_time(int seconds){
char str[20];
sprintf(str,"%02d:%02d:%02d",seconds/3600,seconds%3600/60,seconds%60);
return str;
}
int main(){
cin>>n;
priority_queue<persons,vector<persons>,greater<persons>> normal_person;
priority_queue<persons,vector<persons>,greater<persons>> vip_person;
normal_person.push({
INF});
vip_person.push({
INF});
int arrtime,hour,minute,second,playtime,is_vip;
for(int i=0;i<n;i++){
scanf("%d:%d:%d %d %d",&hour,&minute,&second,&playtime,&is_vip);
arrtime=hour*3600+minute*60+second;
playtime=min(playtime*60,120*60);
if(is_vip) vip_person.push({
arrtime,playtime});
else normal_person.push({
arrtime,playtime});
}
priority_queue<tables,vector<tables>,greater<tables>> normal_table;
priority_queue<tables,vector<tables>,greater<tables>> vip_table;
normal_table.push({
-1,INF});
vip_table.push({
-1,INF});
cin>>k>>m;
for(int i=0;i<m;i++){
int id;
cin>>id;
is_vip_table[id]=true;
}
for(int i=1;i<=k;i++){
if(is_vip_table[i])vip_table.push({
i,8*3600});
else normal_table.push({
i,8*3600});
}
while(normal_person.size()>1||vip_person.size()>1){
auto np=normal_person.top();
auto vp=vip_person.top();
int arrtime=min(np.arrtime,vp.arrtime);
while(normal_table.top().end_time<arrtime){
auto nt=normal_table.top();
normal_table.pop();
nt.end_time=arrtime;
normal_table.push(nt);
}
while(vip_table.top().end_time<arrtime){
auto vt=vip_table.top();
vip_table.pop();
vt.end_time=arrtime;
vip_table.push(vt);
}
auto nt=normal_table.top();
auto vt=vip_table.top();
int end_time=min(nt.end_time,vt.end_time);
if(end_time>=21*3600)break;
if(vp.arrtime<=end_time && end_time==vt.end_time)assign(vip_person,vip_table);
else if(np.arrtime<vp.arrtime){
if(nt>vt)assign(normal_person,vip_table);
else assign(normal_person,normal_table);
}
else {
if(nt>vt)assign(vip_person,vip_table);
else assign(vip_person,normal_table);
}
}
sort(person.begin(),person.end());
for(auto it:person){
cout<<get_time(it.arrtime)<<" "<<get_time(it.start_time)<<" "<<it.waitting_time<<endl;
}
cout<<table_cnt[1];
for(int i=2;i<=k;i++)cout<<" "<<table_cnt[i];
cout<<endl;
return 0;
}
1060.他们是否相等 **
- 本题关键在于如何将两字符串转化成题目所给的形式,有很多技巧
- 1.确定
.
的位置(find函数
),并且根据'.'
的位置确定^10
的次数,例如12345.6,'.'
的位置是5,则10^次数是5,如果没有’.'则在最后一位补上
- 2.将
'.'
从原位置删除,在字符串前面添加新的"0."
,并且删除后面所有的前导0,每删除一个0,10的次数就应当减去1
- 3.截取有效位数,返回处理好的新的字符串作比较即可
一般来说处理这种条件较多的字符串题目最有效的方法就是按照题目原意模拟处理字符串
#include
#include
#include
#include
using namespace std;
string change(string a,int n){
int k=a.find('.');
if(k==-1)a+='.',k=a.find('.');
string s=a.substr(0,k)+a.substr(k+1);
while(s.size() && s[0]=='0')s=s.substr(1),k--;
if(s.empty())k=0;
if(s.size()>n)s=s.substr(0,n);
else s+=string(n-s.size(),'0');
s="0."+s+"*10^"+to_string(k);
return s;
}
int main(){
int n;
cin>>n;
string a,b;
cin>>a>>b;
a=change(a,n);
b=change(b,n);
if(a==b)cout<<"YES "<<a<<endl;
else cout<<"NO "<<a<<" "<<b<<endl;
return 0;
}
1073.科学计数法??
- 注意这题是科学计数法表示,就不存在
0.XXXX
这种情况
- 顺便吐槽一下pat甲真傻逼各种莫名其妙过不了还不让看数据
- 题目原意是让我们把科学计数法的数字转化成正常表示的情况
- 1.首先我们保存10次方的系数
- 2.如果系数是负数我们转正常数时在前面添加
0.
并且可能补0
- 3.如果系数是正数我们则考虑小数点的位置,如果系数大于位数则在后面补0
我们统一将数字转成0.XXX的形式,然后再进行移动小数点(相当于10的次数+1),不这样做会过不了pat甲的两个数据不知道为什么
#include
using namespace std;
int main()
{
string s;
cin >> s;
if (s[0] == '-') cout << '-';
int k = s.find("E");
string a = s[1] + s.substr(3, k - 3);
int b = stoi(s.substr(k + 1));
b ++ ;
if (b <= 0) a = "0." + string(-b, '0') + a;
else if (b >= a.size()) a += string(b - a.size(), '0');
else a = a.substr(0, b) + '.' + a.substr(b);
cout << a << endl;
return 0;
}
作者:yxc
链接:https://www.acwing.com/activity/content/code/content/317851/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#include
#include
#include
using namespace std;
int main(){
string s;
cin>>s;
if(s[0]=='-')cout<<"-";
s=s.substr(1);
int k=s.find('E');
string a=s.substr(0,1)+s.substr(2,k-2);
int e=stoi(s.substr(k+1));
string res;
if(e<0)res="0."+string(-e-1,'0')+a;
else {
int len =a.size();
if(e>=len)res=a+string(e-len+1,'0');
else res=a.substr(0,e+1)+"."+a.substr(e+1);
}
cout<<res;
}
1077.Kuchiguse
- 模板题,注意第一行
读入完整数n之后要getchar()
读入一下接下来的换行符
#include
#include
using namespace std;
const int N=110;
string s[N];
int main(){
int n;
cin>>n;
getchar();
for(int i=0;i<n;i++)getline(cin,s[i]);
int len=s[0].size();
string res="";
for(int i=1;i<=len;i++){
string sf=s[0].substr(len-i);
bool flag=true;
for(int j=1;j<n;j++){
if(s[j].size()<i || s[j].substr(s[j].size()-i)!=sf){
flag=false;
break;
}
}
if(flag)res=sf;
}
if(res!="")cout<<res;
else cout<<"nai";
}
1082.中文读数字 **
- 又没全过淦
- 经典分小数位讨论,之前忘了哪题了,这题是四位四位拆开
- 拆开来单独四位四位处理数据,最后整体添加
"Wan,"Yi"
等字符串
- 注意抠数字出来的时候都是低位存在vector低位,高位存在vector高位,这样方便对应哈希
- 如果低位在前的话就要判断
当前数字是对应个十百千哪一位
,如'100800'
抠出高位是10
,但低位在前不知道1对应的是千还是百还是十,并且处理整体的时候不知道10对应的是亿还是万
- 我们处理部分的时候只需要特判"0" 的情况,如果已处理出的字符串末尾不是0(
表示前面有非零数字或者ling打头
)那么我们就输出"ling",并且去掉末尾多余的"ling "
#include
#include
using namespace std;
string num1[] = {
"ling", "yi", "er", "san", "si",
"wu", "liu", "qi", "ba", "jiu"
};
bool check(string s)
{
return s.size() >= 5 && s.substr(s.size() - 5) == "ling ";
}
string work(int n)
{
vector<int> nums;
while (n) nums.push_back(n % 10), n /= 10;
string num2[] = {
"", "Shi", "Bai", "Qian"};
string res;
for (int i = nums.size() - 1; i >= 0; i -- )
{
int t = nums[i];
if (t) res += num1[t] + ' ';
else if (!check(res)) res += "ling ";
if (t && i) res += num2[i] + ' ';
}
if (check(res)) res = res.substr(0, res.size() - 5);
return res;
}
int main()
{
int n;
cin >> n;
if (!n) puts("ling");
else
{
if (n < 0) cout << "Fu ", n = -n;
vector<int> nums;
string num3[] = {
"", "Wan", "Yi"};
while (n) nums.push_back(n % 10000), n /= 10000;
string res;
for (int i = nums.size() - 1; i >= 0; i -- )
{
int t = nums[i];
if (res.size() && t < 1000) res += "ling ";
if (t) res += work(t);
if (t && i) res += num3[i] + ' ';
}
while (check(res)) res = res.substr(0, res.size() - 5);
res.pop_back();
cout << res << endl;
}
return 0;
}
作者:yxc
链接:https://www.acwing.com/activity/content/code/content/317871/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#include
#include
#include
#include
using namespace std;
vector<string> nums;
string has1[10]={
"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
string has2[4]={
"","Shi ","Bai ","Qian "};
string has3[3]={
"","Wan ","Yi "};
bool check(string s){
return s.size()>=5 && s.substr(s.size()-5)=="ling ";
}
string helper(string s){
string res;
int len=s.size();
for(int i=0;i<len;i++){
int t=s[i]-'0';
if(t)res+=has1[t]+' ';
else if(!check(res))res+="ling ";
if(t)res+=has2[len-i-1];
}
if(check(res))res=res.substr(0,res.size()-5);
return res;
}
int main(){
string s;
cin>>s;
string res;
if(!stoi(s))puts("ling");
else {
if(s[0]=='-'){
cout<<"Fu ";
s=s.substr(1);
}
int len =s.size();
nums.push_back(s.substr(0,len%4));
s=s.substr(len%4);
len=s.size();
for(int i=0;i<len;i+=4)nums.push_back(s.substr(i,4));
int len_num= nums.size();
for(int i=0;i<len_num;i++){
int t=stoi(nums[i]);
if(t)res+=helper(nums[i]);
if(t)res+=has3[len_num-i-1];
}
if(check(res))res=res.substr(res.size()-5);
res.pop_back();
cout<<res;
}
}
1084.坏掉的键盘
- 这题要求按照键入的顺序输出值,不能用哈希表了,普通双指针算法就行
#include
#include
#include
#include
using namespace std;
const int N=300;
bool has[N];
int main(){
string s1,s2;
cin>>s1>>s2;
int len1=s1.size(),len2=s2.size();
int i=0,j=0;
s2+='#';
while(i<len1 || j<len2){
if(s1[i]!=s2[j]){
if(s1[i]>='a' &&s1[i]<='z')s1[i]-=32;
if(!has[s1[i]])cout<<s1[i];
has[s1[i]]=true;
i++;
}
else i++,j++;
}
}
1108.求平均值
- 本题利用了
stof
函数的特性,如果转成浮点数的时候不合法,则会抛出一个异常try catch
- 如果没有抛出异常再判断是否超过1000和两位小数即可
#include
#include
#include
using namespace std;
bool check(char a){
return a>='0' && a<='9';
}
int main(){
int n;
cin>>n;
double res=0;
int cnt=0;
while(n--){
string s;
cin>>s;
string c=s;
if(s[0]=='-')s=s.substr(1);
if(!s.size()){
printf("ERROR: %s is not a legal number\n",c.c_str());
continue;
}
int len=s.size();
bool flag1=true;
for(int i=0;i<len;i++){
if(!check(s[i]) && s[i]!='.'){
flag1=false;
break;
}
}
if(flag1){
int k=s.find('.');
if(k!=-1){
int m=s.find('.',k+1);
if(m==-1 && k && len-k-1<=2){
double x=stof(s.c_str());
if(x>1000.0)flag1=false;
}
else flag1=false;
}
else {
int x=stoi(s.c_str());
if(x>1000)flag1=false;
}
}
if(flag1){
double x=stof(c.c_str());
cnt++;
res+=x;
}
else printf("ERROR: %s is not a legal number\n",c.c_str());
}
if(!cnt)printf("The average of 0 numbers is Undefined");
else if(cnt==1)printf("The average of 1 number is %.2lf",res);
else printf("The average of %d numbers is %.2lf",cnt,res/cnt);
}
#include
#include
#include
using namespace std;
int main(){
int n;
cin>>n;
double res=0;
int cnt=0;
while(n--){
string s;
cin>>s;
double x;
bool flag=true;
try{
size_t idx;
x=stof(s,&idx);
if(idx<s.size())flag=false;
}
catch(...){
flag=false;
}
if(x>1000||x<-1000)flag=false;
int k=s.find('.');
if(k!=-1 && s.size()-k-1>2)flag=false;
if(flag)res+=x,cnt++;
else printf("ERROR: %s is not a legal number\n", s.c_str());
}
if(!cnt)printf("The average of 0 numbers is Undefined");
else if(cnt==1)printf("The average of 1 number is %.2lf",res);
else printf("The average of %d numbers is %.2lf",cnt,res/cnt);
}
1124.微博转发抽奖
#include
#include
#include
#include
using namespace std;
const int N=1010;
string c[N];
map<string,bool> has;
int main(){
int n,m,s;
cin>>n>>m>>s;
for(int i=1;i<=n;i++)cin>>c[i];
if(n<s){
cout<<"Keep going...";
return 0;
}
for(int i=s;i<=n;){
if(!has[c[i]]){
cout<<c[i]<<endl;
has[c[i]]=true;
}
else{
i++;
continue;
}
i+=m;
}
return 0;
}
1141.PAT单位排行 ** (结构体排序–多关键字比较)
- 本题需要强调的首先是结构体内部排序的书写
- 本题对精度要求较高,为了避免出现
真实的总分是124
,但用浮点数存储的是123.999999999
的情况,建议在将整数取整之前加上eps
,比如eps可以取 10^-8
- 出现精度问题的原因是本题在计算分数总和时按照
分别计算B级分数再相加
,而和先计算成绩总和再除以1.5
之间就会产生误差
#include
#include
#include
#include
#include
using namespace std;
struct inform{
string name;
double score;
int cnt;
inform():score(0),cnt(0){
}
bool operator< (const inform & t)const{
if(t.score!=score)return score>t.score;
else if(t.cnt!=cnt)return cnt<t.cnt;
else return name<t.name;
}
};
int main(){
int n;
cin>>n;
map<string,inform> has;
while(n--){
string id,school;
double score;
cin>>id>>score>>school;
for(auto & c:school)c=tolower(c);
if(id[0]=='B')score/=1.5;
if(id[0]=='T')score*=1.5;
has[school].score+=score;
has[school].cnt++;
has[school].name=school;
}
vector<inform> schs;
for(auto it:has){
it.second.score=(int)(it.second.score+1e-8);
schs.push_back(it.second);
}
sort(schs.begin(),schs.end());
int idx=1;
int len=schs.size();
cout<<len<<endl;
for(int i=0;i<len;i++){
if(i && schs[i].score!=schs[i-1].score)idx=i+1;
cout<<idx<<" "<<schs[i].name<<" "<<(int)schs[i].score<<" "<<schs[i].cnt<<endl;
}
}
1153. 解码PAT准考证(pair排序)
- 数据范围不大可以直接暴力但是时间卡的很紧,所以一定要用
print输出
并且使用unordered_map
哈希
- 本题涉及到
vector>
的排序,注意vector优先按照pair.first从小到大排序
再按照pair.second
从小到大排序
因为我们需要根据成绩从打到小排序否则按照string字典序排序,利用这个特点将成绩的int值改为负数再排序即可实现从大到小排序
#include
#include
#include
#include
#include
using namespace std;
struct inform {
string rank,site,date,number,id;
int score;
bool operator < (const inform &t )const {
if(t.score!=score)return score>t.score;
else return id<t.id;
}
};
bool cmp (const pair<string,int> a,const pair<string,int> b){
if(a.second!=b.second)return a.second>b.second;
else return a.first<b.first;
}
vector<inform> stus;
int main(){
int n,m;
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m;
while(n--){
string s;
int score;
cin>>s>>score;
string rank,site,date,number;
rank=s.substr(0,1);
site=s.substr(1,3);
date=s.substr(4,6);
number=s.substr(10);
stus.push_back({
rank,site,date,number,s,score});
}
sort(stus.begin(),stus.end());
for(int i=1;i<=m;i++){
int type;
string term;
cout<<"Case "<<i<<":"<<" ";
cin>>type>>term;
cout<<type<<" "<<term<<endl;
if(type==1){
int cnt=0;
for(auto it : stus){
if(it.rank==term){
cout<<it.id<<" "<<it.score<<endl;
cnt++;
}
}
if(!cnt)cout<<"NA"<<endl;
}
if(type==2){
int sum=0,cnt=0;
for(auto it:stus)if(it.site==term)sum+=it.score,cnt++;
if(cnt)cout<<cnt<<" "<<sum<<endl;
else cout<<"NA"<<endl;
}
if(type==3){
unordered_map<string,int> has;
for(auto it:stus)if(it.date==term)has[it.site]++;
int len=has.size();
if(!len)cout<<"NA"<<endl;
else {
vector<pair<string,int>> p;
for(auto it:has)p.push_back(make_pair(it.first,it.second));
sort(p.begin(),p.end(),cmp);
for(auto it : p)cout<<it.first<<" "<<it.second<<endl;
}
}
}
}
#include
#include
#include
#include
#include
using namespace std;
const int N=10010;
struct inform {
string id;
int score;
bool operator < (const inform &t )const {
if(t.score!=score)return score>t.score;
else return id<t.id;
}
}p[N];
int main(){
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)cin>>p[i].id>>p[i].score;
for(int i=1;i<=m;i++){
string type,term;
cin>>type>>term;
printf("Case %d: %s %s\n",i,type.c_str(),term.c_str());
if(type=="1"){
vector<inform> person;
for(int i=0;i<n;i++)if(p[i].id[0]==term[0])person.push_back(p[i]);
sort(person.begin(),person.end());
if(person.size())
for(auto it:person)printf("%s %d\n",it.id.c_str(),it.score);
else printf("NA\n");
}
else if(type=="2"){
int cnt=0,res=0;
for(int i=0;i<n;i++)if(p[i].id.substr(1,3)==term)res+=p[i].score,cnt++;
if(!cnt)printf("NA\n");
else printf("%d %d\n",cnt,res);
}
else {
unordered_map<string,int> has;
for(int i=0;i<n;i++)if(p[i].id.substr(4,6)==term)has[p[i].id.substr(1,3)]++;
if(!has.size())printf("NA\n");
else {
vector<pair<int,string>> room;
for(auto it:has)room.push_back({
-it.second,it.first});
sort(room.begin(),room.end());
for(auto it:room)printf("%s %d\n",it.second.c_str(),-it.first);
}
}
}
}