【CF】Codeforces Round #536 (Div. 2)

cf改题计划 cf round 536 div 2 A 水题模拟
#include<cstdio>
#include<algorithm>
#include<iostream>

using namespace std;
const int maxn = 505;
char s[505][505];
int n;
int cnt;
int main() {
    scanf("%d",&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]=='X'&&s[i-1][j-1]=='X'&&s[i+1][j+1]=='X'&&s[i-1][j+1]=='X'&&s[i+1][j-1]=='X')cnt++;
        }
    }
    printf("%d",cnt);
}
B 真 模拟 用个set照着题目做就可以了
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<set>
#define pr pair<int,int>
#define int long long
using namespace std;
const int maxn = 2e5+5;
int n,m;
int A[maxn],C[maxn];
struct node{
    int co,nm,dy;
};
bool operator<(node aa,node bb) {
    if(aa.co!=bb.co) return aa.co < bb.co;
    if(aa.nm!=bb.nm) return aa.nm < bb.nm;
    return aa.dy < bb.dy;
}
set<node>se;
main() {
    scanf("%I64d%I64d",&n,&m);
    for(int i=1;i<=n;i++) {
        scanf("%I64d",&A[i]);
    }
    for(int i=1;i<=n;i++) {
        scanf("%I64d",&C[i]);
        se.insert((node){C[i],A[i],i}); 
    }
    for(int i=1;i<=m;i++) {
        int ans = 0;
        int t,d; scanf("%I64d%I64d",&t,&d);
        if(!se.size()) {
            puts("0"); continue;
        }
        int o = min(d,A[t]); d-=o; 
        ans += o*C[t];
        se.erase((node){C[t],A[t],t});
        A[t]-=o;
        if(A[t]>0) se.insert((node){C[t],A[t],t});
        while(d>0&&se.size()) {
            node tmp = *se.begin();
            se.erase(tmp);
            o = min(tmp.nm,d);
            d-=o; tmp.nm-=o; A[tmp.dy]-=o;
            ans += o*tmp.co;
            if(tmp.nm>0) se.insert(tmp); 
        }
        if(d==0)printf("%I64d\n",ans);
        else puts("0");
    }

}
C 真 水题模拟。。。先做B的我悔恨不已
#include<stdio.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#define int long long
using namespace std;
const int maxn = 3e5+5;
int n;
int a[maxn];
main() {
    scanf("%I64d",&n);
    for(int i=1;i<=n;i++) {
        scanf("%I64d",&a[i]);
    }
    sort(a+1,a+n+1);
    int ans = 0;
    for(int i=1,j=n;i<j;i++,j--) {
        ans = ans + (a[i]+a[j])*(a[i]+a[j]);
    }
    printf("%I64d",ans);
}
D 直接BFS一下,把下步可以到的点加入小根堆,模拟就可以了。


\#include<iostream> #include<algorithm> #include<cstdio> #include<vector> #include<queue> using namespace std; const int maxn = 2e5+5; vector<int>ve[maxn]; priority_queue<int,vector<int>,greater<int> >q; int n,m; bool mk[maxn]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); ve[x].push_back(y); ve[y].push_back(x);; } q.push(1); while(q.size()) { int x = q.top(); q.pop(); if(mk[x]) continue; mk[x] = 1; printf("%d ",x); for(auto y:ve[x]) { if(!mk[y]) q.push(y); } } }
E 搞出扫描线之后f[i][j]时间i,打扰了j次可以得到最少金钱,顺着DP就可以了。
#include<stdio.h>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<set>
#include<cstring>
#define int long long
using namespace std;
const int maxn = 1e5+5;
int f[205][maxn];
struct node{
    int tm,d,co;
    int op;
}z[maxn*2]; int tot;
bool operator<(node aa,node bb) {
    if(aa.co!=bb.co) return aa.co > bb.co;
    return aa.d > bb.d;
}
bool cmp(node aa,node bb) {
    if(aa.tm!=bb.tm) return aa.tm < bb.tm;
    return aa.op < bb.op;
}
multiset<node>se;
int n,m,k;
main() {
    scanf("%I64d%I64d%I64d",&n,&m,&k);
    memset(f,0x3f,sizeof f);
    f[m][1] = 0;
    for(int i=1;i<=k;i++) {
        int s,t,d,w; scanf("%I64d%I64d%I64d%I64d",&s,&t,&d,&w);
        ++tot; z[tot].tm = s; z[tot].op = 1; z[tot].d = d; z[tot].co = w;
        ++tot; z[tot].tm = t+1; z[tot].op = -1; z[tot].d = d; z[tot].co = w;        
    }
    sort(z+1,z+1+tot,cmp);
    int now = 1;
    for(int t=1;t<=n;t++) {
        while(now<=tot&&z[now].tm<=t) {
            if(z[now].op==1) {
                se.insert(z[now]);
            } else {
                z[now].op = 1;
                se.erase(se.lower_bound(z[now]));
            }
            now++;
        }
        if(se.size()) {
            node tmp = *se.begin();
            if(f[0][t]!=f[0][0])
                f[0][tmp.d+1] = min(f[0][tmp.d+1],f[0][t]+tmp.co);
            for(int i=1;i<=m;i++) {
                if(f[i][t]!=f[0][0]) {
                    f[i][tmp.d+1] = min(f[i][tmp.d+1],f[i][t]+tmp.co);
                    f[i-1][t+1] = min(f[i][t],f[i-1][t+1]);
                }
            }
        } else {
            for(int i=0;i<=m;i++) {
                f[i][t+1] = min(f[i][t+1],f[i][t]);
            }
        }
    }
    int ans = 1e18;
    for(int i=0;i<=m;i++) ans = min(ans,f[i][n+1]);
    printf("%I64d",ans);
}
F 矩阵乘法很好想到,,,主要问题是在mod 998244353意义下已知b,k求x^k == b 的x.(即k次剩余) 由于有原根,那么g^(r * k ) == g ^ o 已知k,o,求r,那么 r * k == o (mod p-1),利用扩欧解一下这个方程,能解出来就OK,解不出来就无解。 对于中间求o要用BSGS O(k^3logn + sqrt(998244353) ) 具体见: codeforces1106F
posted @ 2019-02-21 18:26  Newuser233  阅读(5)  评论(0)    收藏  举报