1 字符串专题

一切需要使用的 函数or语法:
to_string(a+b)
stoi(s)
stof(s,&idx) idx返回用了几个字符,0.12abc
tolower©
toupper©
getline(cin,s)
pos = s.find(‘.’)
printf(“%s”,s.c_str())
printf(“%.2lf”,double)
s.substr(pos,n) //不会改变s

1、字符串转换✔

to_string(a+b);
1001 A+B Format

#include<iostream>
#include<cstring>
using namespace std;

int main(){
	int a,b;
	cin>>a>>b;
	int c=a+b;
	string s = to_string(c);

			string ans;  //头插法
	int cnt=0;
	for(int i=s.size()-1;i>=0;i--){
		res = s[i]+res;
		cnt++;
		if(cnt %3 ==0 && i && c[i-1] !='-') res =','+res; 
	}

	cout<<s;

}
2、数字拼写✔

1005 Spell It Right

#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
using namespace std;

int main()
{
    vector<int> digits;
    char digit;
    while(cin>>digit){
        digits.push_back(digit-'0');
    }
    int sum= accumulate(digits.begin(),digits.end(),0);
    vector<string> numbers={"zero","one","two","three","four","five","six","seven","eight","nine"};
    string ans=to_string(sum);
    for(int i=0;i<ans.size();i++){
        cout<<numbers[ ans[i]-'0'];
        if(i!=ans.size()-1) cout<<" ";
    }
}
3、签入与签出✔

最大值的初始化:if(!i || a[i]>max) max=a[i];
1006 Sign In and Sign Out

#include<iostream>
#include<cstring>
using namespace std;

int main()
{
    int n;
    cin>>n;
    string id[n],in[n],out[n];
    for(int i=0;i<n;i++){
        cin>>id[i]>>in[i]>>out[i];
    }

    if(n==0) return 0;
    
    int ansin,ansout;
    string max,min;
    for(int i=0;i<n;i++){
        if(!i || in[i] < min) {
            min = in[i];
            ansin = i;
        }
        if(!i || out[i] > max) {
            max = out[i];
            ansout = i;
        }
    }

    cout<<id[ansin]<<" "<<id[ansout]<<endl;
    
    
    
}
4、密码✔

难以辨认的字符的修改;
输入不用全存起来。
用临时变量存一下,然后根据需要才存入数组。int a[N],每次a[m]赋值,m++。
1035 Password

#include<iostream>
#include<vector>
#include<cstring>
using namespace std;

const int N = 1000+10;


int main(){
    int n;
    cin>>n;
    string name[n],password[n];
    vector<int> ans;
    for(int i=0;i<n;i++){
        cin>>name[i]>>password[i];
        ans.push_back(i);
        int sum=0;
        for(auto &a : password[i]){
            if(a=='1') a='@';
            else if (a=='0') a='%';
            else if (a=='l') a='L';
            else if (a=='O') a='o';
            else sum++;
        }
        if(sum==password[i].size() ) ans.pop_back();
    }
    
    int m=ans.size();
    if (m==0) {
        if(n==1) cout<<"There is 1 account and no account is modified";
        else    cout<< "There are " +  to_string(n) + " accounts and no account is modified";
    }
    else{
        cout<<m<<endl;
        for(auto i:ans){
            cout<<name[i]<<" "<<password[i]<<endl;
        }
    }

    return 0;
}
5、最高分&最低分✔

个人觉得我自己这里处理的不错
1036 Boys vs Girls

#include<iostream>
#include<cstring>
using namespace std;

int main(){
    int n;
    cin>>n;
    
    string fname,fid;int fscore=-1;
    string mname,mid;int mscore=101;

    for(int i=0;i<n;i++){
        string name,id;
        char gender;int score;
        cin>>name>>gender>>id>>score;
        if(gender=='F'){
            if(score > fscore){
                fscore = score;
                fname = name;
                fid = id;
            }
        }
        else{
            if(score < mscore){
                mscore = score;
                mname = name;
                mid = id;
            }
            
        }
    }

    
    if(fscore==-1) cout<<"Absent"<<endl;
    else cout<<fname<<" "<<fid<<endl;

    if(mscore==101) cout<<"Absent"<<endl;
    else cout<<mname<<" "<<mid<<endl;
    
    if(fscore==-1 || mscore==101) cout<<"NA"<<endl;
    else  cout<<fscore-mscore<<endl;



    return 0;
}
6、字符串减法✔

getline(cin,s)
unordered_set
1050 String Subtraction

#include<iostream>
#include<cstring>
#include<unordered_set>
using namespace std;
int main(){
    string s1,s2;
    getline(cin,s1);
    getline(cin,s2);
    unordered_set<char> S;
    for(auto &c:s2){
        S.insert(c);
    }

    string ans;
    for(auto &c:s1){
        if(S.count(c)==0) ans +=c;
    }
    cout<< ans << endl;
}
7、出现次数最多的单词⭐

大小写 tolower©、toupper©
通过双指针:外层 i 对不需要的过滤,内层 j 获取每一个单词。
出现次数最多(别给那套用map了)就正常一个unorder_map,然后遍历一遍,是On的,不然你排序是nlogn的
1071 Speech Patterns

#include<iostream>
#include<cstring>
#include<unordered_map>
using namespace std;

bool check(char c){
    if(c>='0' && c<='9') return true;
    else if(toupper(c)>='A' && toupper(c)<='Z') return true;
    else return false;
}

int main (){
    string s;
    getline(cin,s);
    unordered_map<string,int> words;
    for(int i=0;i<s.size();i++){
        if(check(s[i])){
            string word;
            int j=i;
            while ( check(s[j]) && j<s.size() ) word+=tolower(s[j++]);
            words[word]++;
            i=j;
        }
        

    }


    string answord;
    int ans=-1;
    for(auto &word:words){
        if(word.second > ans || (word.second==ans && word.first<answord)){
            answord=word.first;
            ans = word.second;
        }
    }
    cout<<answord<<" "<<ans<<endl;
}
8、解密-约会日期✔

1061 Dating

#include<iostream>
#include<cstring>
using namespace std;
int main(){
    string s1,s2,s3,s4;
    cin>>s1>>s2>>s3>>s4;

    int n=s1.size();
    int i=0;
    for(;i<n;i++){
        if(s1[i]==s2[i]){
            if(s1[i]=='A') cout<<"MON ";
            else if(s1[i]=='B') cout<<"TUE ";
            else if(s1[i]=='C') cout<<"WED ";
            else if(s1[i]=='D') cout<<"THU ";
            else if(s1[i]=='E') cout<<"FRI ";
            else if(s1[i]=='F') cout<<"SAT ";
            else if(s1[i]=='G') cout<<"SUN ";
            else continue;
            break;
        }
    }
    i++;
    for(;i<n;i++){
        if(s1[i]==s2[i]){
            if(s1[i] >='0' && s1[i]<='9') cout<<"0"<<s1[i]<<":";
            else if(s1[i] >='A' && s1[i]<='N') cout<<10+(int)(s1[i]-'A')<<":";
            else continue;
            break;
        }
    }

    n=s3.size();
    for(int i=0;i<n;i++){
        if(s3[i]==s4[i] && (          (s3[i]>='a' && s3[i]<='z')||(s3[i]>='A' && s3[i]<='Z')      )   ) {
            if(i<10) cout<<"0"<<i<<endl;
            else cout<<i<<endl;
            break;
        }
    }
}

9、电话账单✔

map里面放vector
y总计算费用(前缀和)好像确实比我方便很多。我自己的我写的什么JB,艹
1016 Phone Bills

//先将每个人的记录存储,然后排序进行筛选
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<numeric>
#include<iomanip>
using namespace std;

vector<double> cost;
double day_cost;

struct Record{
    string time;
    string flag;
};

bool cmp(Record a,Record b){
    return a.time<b.time;
}

void charge_day(string begin,string end,int &time,double &charge){
    string beginh=begin.substr(0,2),endh=end.substr(0,2);
    begin=begin.substr(3);
    end=end.substr(3);
    if(beginh==endh){
        int temp=stoi(end)-stoi(begin);
        time+=temp;  //聊了30分钟
        charge+=cost[stoi(beginh)]*temp;
    }
    else{
        int h=stoi(beginh);
        time+=60-stoi(begin);
        charge+=cost[h]*(60-stoi(begin));
        h++;
        for(;h<stoi(endh);h++ ){
            time+=60;
            charge+=cost[h]*60;
        }
        time+=stoi(end);
        charge+=cost[h]*stoi(end);
    }
    
    
    
    
}

void charge(string begin,string end,double &total){  //这样有一个坏处,就是不能递归了
    int time=0;
    double charge=0;
    //先算天
    string beginday=begin.substr(0,2),endday=end.substr(0,2);
    begin=begin.substr(3);
    end=end.substr(3);
    if( begin<=end){
        time+=24*60*(stoi(endday)-stoi(beginday));
        charge+=day_cost*(stoi(endday)-stoi(beginday));
        charge_day(begin,end,time,charge);        
    }
    else if(begin>end){
        charge_day(end,begin,time,charge);
        time = 24*60-time;
        charge = day_cost-charge;
        time+=24*60*(stoi(endday)-stoi(beginday)-1);
        charge+=day_cost*(stoi(endday)-stoi(beginday)-1);
        
    }
    
    
    cout<<time<<" $"<<charge/100<<endl;
    total+=charge;
}

int main()
{
    cout<<setiosflags( ios::fixed )<<setprecision(2);
    //1 初始化cost
    for(int i=0;i<24;i++){
        double temp;
        cin>>temp;
        cost.push_back(temp);
    }
    day_cost=60*accumulate(cost.begin(),cost.end(),0);
    //2 构建存储结构
    int k;
    cin>>k;
    map<string,vector<Record> > data;
    //2.1 先储存信息 ,后计算总时间和价格       data[lili]=vector< 1/22 17.30         >
    for(int i=0;i<k;i++){
        string name;
        Record record;
        cin>>name>>record.time>>record.flag;
        // if( !data.count(name) ){
        //     vector<Record> ini;
        //     data[name]=ini;
        // } 
        data[name].push_back(record);
    }
    //2.2 排序
    for(auto it=data.begin();it!=data.end();it++){
        sort( (it->second).begin(),    (it->second).end(),cmp           );
    }
    //2.3 删除无效项
    for(auto it=data.begin();it!=data.end();it++){
        //对于每个name进行遍历
        for(auto itv=it->second.begin();itv!=it->second.end();){
            //成对的找,如果当前一对【1,2】不满足条件,删除1,继续找【2,3】
            if(   itv == it->second.end()-1   ) it->second.erase(itv);
            else if( !(itv->flag=="on-line" && (itv+1)->flag=="off-line")        ) it->second.erase(itv);
            else{
                itv+=2;
            }
        }

    }
    
    
    
    //二**直接对data中的数据进行加工输出即可*************************************************************************************
    
    for(auto it=data.begin();it!=data.end();it++){
        if(it->second.size()==0) continue;
        //输出每个人的标题
        string month= it->second[0].time.substr(0,2);
        cout<<it->first<<" "<<month<<endl;
        //逐项输出账单,并记录总账单。
        double total=0;
        for(auto itv=it->second.begin();itv!=it->second.end();){
            //获取前后时间
            string begin=itv->time.substr(3);
            itv++;
            string end=itv->time.substr(3);
            itv++;
            //统计信息
            cout<<begin<<" "<<end<<" ";
            charge(begin,end,total); //计算后函数中直接输出
        }
        //cout<<"Total amount: $"<<total/100<<endl;
        printf("Total amount: $%.2f", total/100.00);
        cout<<endl;
    }
    
    
    
}
10、银行排队✔

时间用秒计时;堆里存的是当前窗口的预计的开始服务的时间;
对于每个客户,根据now 与 peoples[i].arrive_time 判断来早了还是来晚了。
来早了,无等待时间,并加入堆中,他被服务完的时刻是peoples[i].server_time + now
来晚了,新增等待时间,加入堆中。他被服务完的时刻是peoples[i].server_time + peoples[i].arrive_time
1017 Queueing at Bank

#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;

const int N = 10000+10;
int n,k;
struct People{
    int arrive_time;
    int server_time;
    bool operator < (People x){
        return arrive_time<x.arrive_time;
    }
    
}peoples[N];



int main(){
    cin>>n>>k;
    for(int i=0;i<n;i++){
        int h,m,s,l;
        scanf("%d:%d:%d %d",&h,&m,&s,&l);
        int arrive_time,server_time;
        arrive_time = h*3600 + m*60 + s;
        server_time = min(l,60) * 60;
        peoples[i] = {arrive_time,server_time};
    }
    sort(peoples,peoples+n);

    priority_queue<int,vector<int>,greater<int> > windows;   //堆里存的是当前窗口的预计的开始服务的时间
    for(int i=0;i<k;i++) windows.push(8*3600);   
    int wait_time=0;
    int ignore=0;
    for(int i=0;i<n;i++){
        if(peoples[i].arrive_time > 17*3600) {
            ignore++;
            continue;
        } 
        int now = windows.top();windows.pop();
        if(now >= peoples[i].arrive_time){
            wait_time += now - peoples[i].arrive_time;
            windows.push(now + peoples[i].server_time);
        }
        else {
            windows.push(peoples[i].arrive_time + peoples[i].server_time);
        }
    }
    printf("%.1lf\n",(double)(wait_time  )/60.0 /(n-ignore)  );
}
11、乒乓球

1026 Table Tennis


12、 转化为科学计数法✔

pos = s.find(‘.’);去除小数点;
1060 Are They Equal

#include<iostream>                    //科学计数法  ,N表示现实多少位
using namespace std;                    //先去掉前置0    (如果是0.004这种)还需要判断后继续去前置0
                                        //之后分别计算数字部分和指数部分就行了

string solve(int N,string s){
    int exp=0;
    
    while(s.size() >0 && s[0]=='0'){
        s.erase(s.begin());
    }
    if(s[0] =='.'){         //去掉前导0是小数点,说明s后面是小数
        s.erase(s.begin());
        while(s.size() >0 && s[0]=='0'){
            s.erase(s.begin());
            exp--;
        }
    }
    else{               //说明是整数部分
        int i=0;
        for( ;i<s.size() && s[i]!='.';i++){
            exp++;
        }
        if(i<s.size()){
            s.erase(s.begin()+i);
        }
        //删除这个小数点即可,得到想要的整个数字部分。因为咱们指数已经确定了
        //或者你在后面读取的时候对小数点进行讨论,但可能更麻烦
    }
    if(s.size()==0) exp=0;
    //已经将字符串处理完,现在仅包含数字部分(指数已确定所以不用管),且为空的话,重新更新指数为0.
    

    string ans="";
    for(int i=0,k=0;k<N;i++,k++){   //补0操作
        if( i <s.size() ) ans+=s[i];    //如果字符串没结束,赋值
        else ans+='0';                  //  如果结束了,补0
    }
    
    ans="0."+ans+"*10^"+to_string(exp);
    
    return ans;
}


int main()
{
    int N;
    string A,B,resA,resB;
    cin>>N>>A>>B;
    resA = solve(N,A);
    resB = solve(N,B);
    if(resA==resB)
        cout<<"YES "<<resA<<endl;
    else
        cout<<"NO "<<resA<<" "<<resB<<endl;
    
    
    
    
    
    return 0;
}
13. 科学计数法转化为传统计数✔

记录正负号;
指数部分根据 正负分别处理。
指数为正时,可能消除小数点,也要分两种情况处理。
1073 Scientific Notation

#include<iostream>
#include<cstring>
using namespace std;

int main(){
    string s;
    cin>>s;
    int flag=false;
    if(s[0]=='-') flag=true;
    s=s.substr(1);
    int e_pos = s.find('E');
    if(s[e_pos+1]=='-'){  
        int n = stoi(s.substr(e_pos+2))-1;  //这里默认指数>0
        s = s.substr(0,e_pos);
        s = s.substr(0,1) + s.substr(1+1,e_pos-2);
        while(n--){
            s = "0" +s;
        }
        s= "0."+s;
    }
    else {
        int n = stoi(s.substr(e_pos+2));  //这里默认指数>0
        s = s.substr(0,e_pos);
        if(n+2 >= s.size() ){  //没有小数点
            n = n+2-s.size();
            s = s.substr(0,1) + s.substr(1+1,e_pos-2);
            while(n--){
                s = s +"0";
            }
        }
        else{    //有小数点
            s = s.substr(0,1) + s.substr(1+1,e_pos-2);
            s = s.substr(0,n+1)   +"." + s.substr(n+1);
        }


        
    }
    
    if(flag) s = '-'+s;
    cout<<s<<endl;
}
14. Kuchiguse✔

字符串结尾口头禅。
1077 Kuchiguse

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 110;
int n;

char ans[257];
int k;

int main(){
    cin>>n;
    string a;getline(cin,a);
    for(int i=0;i<n;i++){
        string s;
        getline(cin,s);

        reverse(s.begin(),s.end());
        if(i==0){
            for(int j =0;j<s.size();j++) ans[j]=s[j];
            k=s.size();
        }
        else{
            int j=0;
            for(;j<k && j<s.size();j++){
                if(ans[j]!=s[j] ) {
                    break;
                }
            }
            k=j;
        }
    }
    if(k==0) cout<<"nai"<<endl;
    else{
        for(int i=k-1;i>=0;i--){
            cout<<ans[i];
        }
        cout<<endl;
    }
}
15. 中文读数字

全是特殊情况,判断处理。
1082 Read Number in Chinese



16、坏掉的键盘✔

逗号运算符!!!
双指针
1084 Broken Keyboard

#include<iostream>
#include<unordered_set>
#include<cstring>
using namespace std;
int main(){
    string s1,s2;
    cin>>s1>>s2;
    int i=0,j=0;
    unordered_set<char> S;
    while(i<s1.size()){
        char x = toupper(s1[i]);
        char y = toupper(s2[j]);
        if(x==y) j++;
        else{
            if(S.count(x)==0) cout<<x,S.insert(x);
        }
        i++;
    }
    
    cout<<endl;
    
}
17、判断实数是否合法 ⭐

try_catch 实现;
stof的用法
pos=s.find(‘.’)
%.2lf
1108 Finding Average

#include<iostream>
#include<cstring>

using namespace std;

bool check(string s){
    try{
        size_t idx;
        double x = stof(s,&idx);
        if(idx<s.size()) return false;
        if(x<-1000 || x>1000) return false;
        int pos = s.find('.');
        if(pos!=-1 && idx-pos-1>2) return false;
    }
    catch(...){
        return false;
    }
    return true;
    
    
}


int main(){
    int n;
    cin>>n;
    int cnt=0;double sum=0;
    for(int i=0;i<n;i++){
        string s;
        cin>>s;
        if(check(s)) sum+=stof(s),cnt++;
        else cout<<"ERROR: "<<s<<" is not a legal number"<<endl;
    }

    if(cnt==0) cout<<"The average of 0 numbers is Undefined"<<endl;
    else if(cnt==1) cout<<"The average of 1 number is ",
                    printf("%.2lf\n",sum);
    else 
        cout<<"The average of "<<cnt<<" numbers is ",
        printf("%.2lf\n",sum/cnt);
}
18、间隔抽奖✔

1124 Raffle for Weibo Followers

#include<iostream>
#include<cstring>
#include<unordered_set>

using namespace std;
int main(){
    int n,skip,pos;
    cin>>n>>skip>>pos;
    pos--;

    unordered_set<string> S;
    for(int i=0;i<n;i++){
        string name;
        cin>>name;

        if( i==pos ) {
            if( S.count(name)==0 )  cout<<name<<endl,S.insert(name);
            else pos-=skip-1;
            pos+=skip;
        }           
    }

    if(S.empty()==1) cout<<"Keep going..."<<endl;
}
19、学校排名⭐

比较经典的一个题目
1:用map存键值对。
2:map中的值用 struct结构体存。
3:遍历map中的值存入vector进行sort排序。
4:重载结构体的比较运算符。
5:double转int 的精度需要加1e-8。
6:计算排名的rank计算。
1141 PAT Ranking of Institutions

#include<iostream>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<algorithm>
using namespace std;

struct school{
    string name;
    double score;
    int cnt;

    bool operator < (school a){
        if(a.score!=score) return score>a.score;
        else if(a.cnt!=cnt) return cnt < a.cnt;
        else return name<a.name;
    }
};
int main(){
    int n;
    cin>>n;

    unordered_map<string,school> ans1;
    vector<school> ans2;
    for(int i=0;i<n;i++){
        string id,institute;double score;
        cin>>id>>score>>institute;
        for(int i=0;i<institute.size();i++) institute[i]=tolower(institute[i]);
        ans1[institute].name=institute;
        ans1[institute].cnt+=1;
        if(id[0]=='B') ans1[institute].score+=score/1.5;
        else if (id[0]=='A') ans1[institute].score+=score;
        else if (id[0]=='T') ans1[institute].score+=score*1.5;
    }

    for(auto &m :ans1){
        m.second.score = (int) (m.second.score +1e-8);
        ans2.push_back(m.second);
    }
    sort( ans2.begin(),ans2.end() );

    int rank=1;
    cout<<ans2.size()<<endl;
    for(int i=0;i<ans2.size();i++){
        if((int)ans2[i].score != (int)ans2[i-1].score) rank = i+1;
        
        cout<<rank<<" "<<ans2[i].name<<" "<<(int)ans2[i].score<<" "<<ans2[i].cnt<<endl;
    }

    
}
20、PAT准考证信息统计✔

会了上题的经典之后,这一题虽然多,但都是一个逻辑了。
另外一点是,这一点用cout会超时,改成printf过了。。。
s.substr(pos,n) //不会改变s
1153 Decode Registration Card of PAT

#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<unordered_map>
using namespace std;

const int N=10000+10,M=110;
int n,m;
string id[N];int score[N];

struct person{
    string id;
    int score;
    bool operator < (person t){
        if(score != t.score) return score>t.score;
        else return id < t.id;
    }
};

struct Site{
    string site;
    int cnt;
    bool operator < (Site s){
        if(cnt!=s.cnt) return cnt> s.cnt;
        else return site<s.site;
    }
};

void query1(string order){
    vector<person> persons;
    for(int i=0;i<n;i++){
        person t;
        t.id=id[i];
        t.score=score[i];
        if(id[i][0]==order[0]) persons.push_back(t);
    }
    if(persons.size()==0) printf("NA\n");
    else{
        sort(persons.begin(),persons.end());
        for(auto &t:persons){
            printf("%s %d\n",t.id.c_str(),t.score); 
        }
    }
}

void query2(string order){
    int cnt=0;int sum=0;
    for(int i=0;i<n;i++){
        if( id[i].substr(1,3)  == order){
            cnt++;
            sum+=score[i];
        }
    }
    if(cnt==0) cout<<"NA"<<endl;
    else 
    cout<<cnt<<" "<<sum<<endl;
}

void query3(string order){
    unordered_map<string,int> date;
    for(int i=0;i<n;i++){
        string site=id[i].substr(1,3);
        if( id[i].substr(4,6)  == order){
            date[site]+=1;
        }
    }

    vector<Site> sites;
    for(auto &m:date){
        Site site;
        site.site = m.first;
        site.cnt = m.second;
        sites.push_back(site);
    }
    if(sites.size()==0) cout<<"NA"<<endl;
    else{
        sort(sites.begin(),sites.end());
        for(auto &t:sites){
            printf("%s %d\n",t.site.c_str(),t.cnt);
        }
    }
    

}




int main(){
    cin>>n>>m;

    for(int i=0;i<n;i++){
        cin>>id[i]>>score[i];
    }

    for(int i=0;i<m;i++){
        int type;string order;
        cin>>type>>order;
        cout<<"Case "<<i+1<<": "<<type<<" "<<order<<endl;
        if(type==1) query1(order);
        else if(type==2) query2(order);
        else if(type==3) query3(order);
    }
    return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值