A - Duplex Printing

思路:判断一下奇偶就好了

#include<iostream>
#include<algorithm>
#include<cstring>
 using namespace std;
 int main()
 {
     int n;
     cin>>n;
     int ans=n/2;
     if(n%2!=0) ans++;
     cout<<ans<<endl;
     return 0;
 }
View Code

B - Bingo

思路:按照题意模拟一下即可

#include<iostream>
#include<algorithm>
 using namespace std;
 int a[4][4],flag[4][4];
 int main()
 {
     for(int i=1;i<=3;i++)
         for(int j=1;j<=3;j++)
             cin>>a[i][j];
     int n,ans=0,x;
     cin>>n;
     while(n--){
         cin>>x;
         for(int i=1;i<=3;i++){
             for(int j=1;j<=3;j++)
                 if(a[i][j]==x) flag[i][j]=1;
         }
     }
    for(int i=1;i<=3;i++){
        int cnt=0;
         for(int j=1;j<=3;j++)
             if(flag[i][j]) cnt++;
         if(cnt==3){
             cout<<"Yes"<<endl;
             return 0;
         }
    }
    for(int i=1;i<=3;i++){
        int cnt=0;
         for(int j=1;j<=3;j++)
             if(flag[j][i]) cnt++;
         if(cnt==3){
             cout<<"Yes"<<endl;
             return 0;
         }
    }
    if(flag[1][1]+flag[2][2]+flag[3][3]==3||flag[1][3]+flag[2][2]+flag[3][1]==3){
        cout<<"Yes"<<endl;
        return 0;
    }
    cout<<"No"<<endl;
    return 0;
 }
View Code

C - Guess The Number

思路:开一个数组存每个位置上的数即可,如果矛盾了或者出现前置0就不行,要注意一些特殊情况

#include<iostream>
#include<algorithm>
 using namespace std;
 int a[4];
 int main()
 {
     int n,m,x,y,flag=0;
     cin>>n>>m;
    a[1]=a[2]=a[3]=-1;
    for(int i=1;i<=m;i++){
        cin>>x>>y;
        if(a[x]!=-1&&a[x]!=y){
            flag=1;
            break;
        } 
        a[x]=y;
    }
    if(flag==1){
        cout<<-1<<endl;
        return 0;
    }
    if(a[1]==0&&n!=1){
        cout<<-1<<endl;
        return 0;
    }
    if(n==1&&a[1]==-1){
        cout<<0<<endl;
        return 0;
    }
    for(int i=1;i<=n;i++){
        if(a[i]==-1&&i==1){
            cout<<"1";
            continue;
        } 
        if(a[i]==-1) cout<<"0";
        else cout<<a[i];
    }
 }
View Code

D - Friend Suggestions(并查集)

思路:由于关系具有传递性,所以我们用并查集来存储与查询关系,对个每个人的答案,就为其所在连通块大小减去,他的直接好友再减去一个连通块内有封锁关系的朋友

#include<iostream>
#include<algorithm>
#include<vector>
 using namespace std;
 const int maxn=1e5+10;
 typedef long long ll;
 int fa[maxn],siz[maxn];
 vector<int> a[maxn],b[maxn];
 int find(int x){return (x==fa[x])?x:fa[x]=find(fa[x]);}
 int main()
 {
     int n,m,k,u,v;
     scanf("%d%d%d",&n,&m,&k);
     for(int i=1;i<=n;i++){
         fa[i]=i;
         siz[i]=1;
     }
    for(int i=1;i<=m;i++){
        scanf("%d%d",&u,&v);
        int f1=find(u),f2=find(v);
        if(f1!=f2){
            siz[f1]+=siz[f2];
            fa[f2]=f1;
        }
        a[u].push_back(v);
        a[v].push_back(u); 
    }
    for(int i=1;i<=k;i++){
        scanf("%d%d",&u,&v);
        b[u].push_back(v);
        b[v].push_back(u);
    } 
    for(int i=1;i<=n;i++){
        int ans=siz[find(i)]-1;
        ans-=a[i].size();
        for(int j=0;j<b[i].size();j++){
            if(find(i)==find(b[i][j]))
                ans--;
        }    
        cout<<ans<<" ";
    }
    return 0;
 }
View Code

E - Simple String Queries(线段树/STL)

思路:

方法一:建立26棵线段树

方法二:建立26个set,每个set存相应字母出现的位置

    对于修改,先在原来的字母对应的set中删除位置,再在更新的字母对应的set中插入位置

    由于set中元素都为有序的,所以每次询问,在每个set中进行二分找l如果找到的元素小于等于r答案就加一

#include<iostream>
#include<algorithm>
#include<set>
 using namespace std;
 set<int> a[26];
 string temp;
 int main()
 {
    cin>>temp;
    int n,op,pos,l,r;
    char ch;
    for(int i=0;i<temp.size();i++) a[temp[i]-'a'].insert(i+1);
    scanf("%d",&n);
    while(n--){
        scanf("%d",&op);
        if(op==1){
            cin>>pos>>ch;
            a[temp[pos-1]-'a'].erase(pos);
            temp[pos-1]=ch;
            a[temp[pos-1]-'a'].insert(pos);
        }
        else{
            cin>>l>>r;
            int num=0;
            for(int i=0;i<26;i++){
                set<int>::iterator it;
                it=a[i].lower_bound(l);
                if(it!=a[i].end()&&*it<=r) num++;
            }
            cout<<num<<endl;
        }
    }
    return 0;
 }
View Code