Codeforces Round #300

https://codeforces.com/contest/538

A.Cutting Banner

题意给出一个字符串,你可以删除一段,看能不能拼成codeforces

#include<bits/stdc++.h>
using namespace std;
int main(){
    string s;
    cin>>s;
    int fg=0;
    int len=s.size();
    for (int i = 0; i < len; i++) {
        for (int j = i+1; j <= len; j++) {
            string pref = s.substr(0, i);
            string suf = s.substr(j);
            if (pref + suf == "CODEFORCES") {
                printf("YES\n");
                return 0;
            }
        }
    }
    printf("NO\n");

}
View Code

B. Quasi Binary

给出一个整数,将其拆分成最小的quasibinary数(定义只含0,1的数 例如:10,11,100,101,111)

思路:从高位开始拆分,依次往下

#include<bits/stdc++.h>
using namespace std;
vector<int> v[11];
bool vis[11];
int a[11];
int cnt;
int main(){
    int n;
    cin>>n;
    while(n){
        a[++cnt]=n%10;
        n/=10;
    }
    int ans=0;
    for(int i=cnt;i>=1;i--){
         for(int k=1;k<=10;k++){
             if(a[i]!=0){
                 v[k].push_back(1);
                 if(!vis[k]){
                     ans++;
                     vis[k]=1;
                 }
                 a[i]--;
             }else {
                 if(v[k].size()!=0) {
                     if(!vis[k]){
                     ans++;
                     vis[k]=1;
                     }
                 v[k].push_back(0);
                 }
             }
         }
    }
    cout<<ans<<endl;
    for(int i=1;i<=9;i++){
        int fg=0;
        for(auto x:v[i]){
            cout<<x;
            fg=1;
        }
        if(fg)
        cout<<" ";
    }
}
View Code

C. Tourist's Notes

一共n天,以及第mi天的高度,保证任意两天的高度距离相差<=1 求最高的高度

思路:贪心,能从已知的相邻的两天的高度,求出一个山型的最高距离即可 然后处理第一天和最后一天

#include<bits/stdc++.h>
using namespace std;
struct node{
    int t,h;
}p[100005];
int main(){
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=k;i++) cin>>p[i].t>>p[i].h;
        //sort(p+1,p+1+k);
    int Max=0;
    for(int i=1;i<=k;i++){
        if(i==1){
           Max=p[i].h+p[i].t-1;
        }else {
            if(abs(p[i].h-p[i-1].h)>p[i].t-p[i-1].t){
                return 0*puts("IMPOSSIBLE");
            }else {
                int pos=p[i].t-p[i-1].t;
                int a=p[i].h;
                int b=p[i-1].h;
                int z=abs(a-b);
                int ha=pos-z;
                Max=max(Max,max(a,b)+ha/2);
            }
        }
    }
    Max=max(Max,p[k].h+n-p[k].t);
    cout<<Max<<"\n";
    return 0;
}
View Code

D.Weird Chess

给出一个矩阵,o代表棋子,x代表可攻击到的范围,.代表攻击不到的。我们需打印个(2n-1)*(2n-1)的矩阵即可

思路:我们把不能‘.'号全部输出到矩阵上然后判断'x'是否会与'.'重叠,重叠则输出no

#include<bits/stdc++.h>
using namespace std;
char s[105][105];
bool vis1[105][105];
bool vis2[105][105];
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    scanf("%s",s[i]+1);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(s[i][j]=='o'){
                for(int k=1;k<=n;k++){
                    for(int z=1;z<=n;z++){
                        if(s[k][z]=='.'){
                            vis1[n+k-i][n+z-j]=1;//把'.'
                        }
                    }
                }
            }
        }
    }
for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(s[i][j]=='o'){
                for(int k=1;k<=n;k++){
                    for(int z=1;z<=n;z++){
                        if(s[k][z]=='x'&&!vis1[n+k-i][n+z-j]){
                            vis2[k][z]=1;
                        }//判断是否能攻击到 '.' 的位置
                    }
                }
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(s[i][j]=='x'){
                if(vis2[i][j]!=1){
                    return 0*puts("NO");
                }
            }
        }
    }
    puts("YES");//如果所有'x'都合法
    for(int i=1;i<=n*2-1;i++,puts("")){
        for(int j=1;j<=n*2-1;j++){
            if(i==n&&j==n) cout<<"o";
            else if(vis1[i][j]) cout<<".";
            else cout<<"x";
        }
    }
    return 0;
}
View Code

E. Demiurges Play Again

树形博弈  待学

F. A Heap of Heaps

构造一个k叉堆,需使得子节点都发育根节点,否则此点算违法点,输出违法点个数

对某个节点造成贡献的儿子节点的值一定小于该节点。 
把节点按值排序,从小到大枚举每个节点。对于k叉堆,它儿子中被处理过的节点数,就是这个点对答案中k叉堆情况的贡献。 

然后我们用树状数组维护一段连续区间小于根节点的值即可

#include<bits/stdc++.h>
#define LL long long
#define mod 1000000007
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int maxn = 200005;
int n;
int ans[maxn];
int tree[maxn];
struct node{
    int val;
    int id;
    bool friend operator < (const node u,const node v){
        if(u.val==v.val) return u.id<v.id;
        return u.val<v.val;
    }
}p[maxn];
int lowbit(int k){
    return k&(-k);
}
void add(int x){
    if(x==0) return;
     while(x<n){
         tree[x]+=1;
         x+=lowbit(x);
     }
}
int get_sum(int x){
    int ans=0;
    while(x){
        ans+=tree[x];
        x-=lowbit(x);
    }
    return ans;
}
void solve(){
    for(int i=0;i<n;i++){
        int id=p[i].id;
            for(int k=1;k<n&&k*id+1<n;k++){
            ans[k]+=get_sum(min(n-1,k*id+k))-get_sum(k*id);//以p[i]为根节点 算贡献
            }
            add(p[i].id);
    }
    for(int i=1;i<=n-1;i++){
        cout<<ans[i]<<" ";
    }
}
int main(){
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>p[i].val;
        p[i].id=i;
    }
    sort(p,p+n);
    solve();
}
View Code

 

猜你喜欢

转载自www.cnblogs.com/MengX/p/10652070.html