The 10th Shandong Provincial Collegiate Programming Contest(8/13)

\[The\ 10th\ Shandong\ Provincial\ Collegiate\ Programming\ Contest\]

\(A.Calandar\)

签到

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
char day[5][20] = {{"Monday"},{"Tuesday"},{"Wednesday"},{"Thursday"},{"Friday"}};
using LL = int_fast64_t;
int T;
void solve(){
    LL now = 0, y, m, d, nxt = 0;
    int cd;
    char s[20];
    scanf("%I64d %I64d %I64d %s",&y,&m,&d,s);
    if(s[0]=='M') cd = 0;
    else if(s[0]=='T' && s[1]=='u') cd = 1;
    else if(s[0]=='W') cd = 2;
    else if(s[0]=='T' && s[1]=='h') cd = 3;
    else cd = 4;
    now = 360 * y + 30 * m + d;
    scanf("%I64d %I64d %I64d",&y,&m,&d);
    nxt = 360 * y + 30 * m + d;
    LL delta = nxt - now;
    cd = ((cd+delta)%5+5)%5;
    printf("%s\n",day[cd]);
}
int main(){
    for(scanf("%d",&T); T; T--) solve();
    return 0;
}

\(B.Flipping\ Game\)

DP
\(f[i][j]\)表示当前第\(i\)轮按开关,和最终状态相反的有\(j\)个的方案数,初始有\(num\)个灯和最终状态不同的话,显然\(f[0][num]=1\)
现在考虑状态转移,\(kk\)表示上一轮与最终状态相反的个数,\(x\)表示有\(x\)个从和最终状态相反的变成和最终状态相同的,\(y\)表示从和最终状态相同的变成和最终状态不同的,则\(f[i][j]=\sum_{valid\ kk}f[i-1][kk]·C(kk,x)·C(n-kk,y)\)
其中需要满足四个约束条件:
1.\(0 \le x \le kk\)
2.\(0 \le y \le n-kk\)
3.\(x + y = m\)
4.\(kk-x+y=j\)
\(3\)和\(4\)联立得到\(x=(kk+m-j)/2\)
然后就可以写了

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 111;
using LL = int_fast64_t;
const LL MOD = 998244353;
int T,n,m,k;
char s1[MAXN],s2[MAXN];
LL fact[MAXN],invfact[MAXN],f[2][MAXN];
LL qpow(LL a, LL b){
    LL res = 1;
    while(b){
        if(b&1) res = res * a % MOD;
        b >>= 1;
        a = a * a % MOD;
    }
    return res;
}
LL C(int A, int B){ return fact[A] * invfact[B] % MOD * invfact[A-B] % MOD; }
void solve(){
    scanf("%d %d %d %s %s",&n,&k,&m,s1,s2);
    int num = 0;
    for(int i = 0; i < n; i++) num += (s1[i]!=s2[i]?1:0);
    memset(f,0,sizeof(f));
    int tag = 0;
    f[tag][num] = 1;
    for(int i = 1; i <= k; i++){
        tag ^= 1;
        memset(f[tag],0,sizeof(f[tag]));
        for(int j = 0; j <= n; j++){
            for(int kk = max(0,j-m); kk <= min(n,j+m); kk++){
                if((kk+m-j)&1) continue;
                int x = ((kk+m-j)>>1);
                if(x<0||x>kk||m-x<0||m-x>n-kk) continue;
                f[tag][j] = (f[tag][j] + f[tag^1][kk] * C(kk,x) % MOD * C(n-kk,m-x)) % MOD;
            }
        }
    }
    printf("%lld\n",f[tag][0]);
}
int main(){
    fact[0] = 1;
    for(int i = 1; i < MAXN; i++) fact[i] = fact[i-1] * i % MOD;
    for(int i = 0; i < MAXN; i++) invfact[i] = qpow(fact[i],MOD-2);
    for(scanf("%d",&T); T; T--) solve();
    return 0;
}

\(C.Wandering\ Robot\)

随便写

#include<bits/stdc++.h>
#pragma GCC optimize("O3")
//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("unroll-loops")
using namespace std;
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int N = 1e5+10;
char a[N];
int32_t main(){
    IOS;
    int _;cin>>_;
    while(_--){
        int n,k; cin>>n>>k;
        cin>>a;
        int ans=0,x=0,y=0;
        for(int i=0;i<n;i++){
            if(a[i]=='R')x++;
            if(a[i]=='L')x--;
            if(a[i]=='U')y++;
            if(a[i]=='D')y--;
            ans=max(ans, abs(x)+abs(y));
        }
        if(k==1){
            cout<<ans<<endl;
            continue;
        }
        int xx=x*(k-1), yy=y*(k-1);
        for(int i=0;i<n;i++){
            if(a[i]=='R')xx++;
            if(a[i]=='L')xx--;
            if(a[i]=='U')yy++;
            if(a[i]=='D')yy--;
            ans=max(ans, abs(xx)+abs(yy));
        }
        cout<<ans<<endl;
    }
    return 0;
}

\(D.Game\ on\ a\ Graph\)

最终状态是一棵树,只和边的数量有关,最多可以删掉\(e-(v-1)\)条边

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
int T,n,v,e;
char s[MAXN];
void solve(){
    scanf("%d %s %d %d",&n,s,&v,&e);
    for(int i = 1; i <= e; i++) scanf("%d %d",&n,&n);
    n = strlen(s);
    putchar(s[(e-(v-1))%n]=='1'?'2':'1'); puts("");
}
int main(){
    for(scanf("%d",&T); T; T--) solve();
    return 0;
}

\(E.BaoBao\ Loves\ Reading\)

\(F.Stones\ in\ the\ Bucket\)

贪心,先变成\(n\)的倍数然后把低于平均数的补齐即可

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
using LL = int_fast64_t;
const int MAXN = 1e5+7;
int T,n;
LL A[MAXN];
void solve(){
    LL res = 0;
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> A[i];
    LL tot = accumulate(A+1,A+1+n,0LL);
    LL del = tot % n, ave = tot / n;
    res = del;
    for(int i = 1; i <= n; i++){
        if(A[i]>ave&&del){
            LL d = min(del,A[i]-ave);
            del -= d;
            A[i] -= d;
        }
        if(!del) break;
    }
    for(int i = 1; i <= n; i++) if(A[i]<ave) res += ave - A[i];
    cout << res << endl;
}
int main(){
    ____();
    for(cin >> T; T; T--) solve();
    return 0;
}

\(G.Heap\)

\(H.Tokens\ on\ the\ Segments\)

优先考虑左端点靠前的,每当遍历到某\(x\)值时,把左端点为\(x\)的线段的右端点加入到优先队列中,把已经超过右边界的线段删去,然后取右端点最靠左的放token

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
int T,n;
pair<int,int> seg[MAXN];
void solve(){
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> seg[i].first >> seg[i].second;
    sort(seg+1,seg+1+n);
    int tot = 0, now = 1;
    priority_queue<int,vector<int>,greater<int>> que;
    for(int cur = 1; now<=n||!que.empty(); ){
        while(now<=n&&seg[now].first==cur){
            que.push(seg[now].second);
            now++;
        }
        while(!que.empty()&&que.top()<cur) que.pop();
        if(!que.empty()){
            tot++;
            que.pop();
        }
        if(!que.empty()) cur++;
        else{
            if(now>n) break;
            else cur = seg[now].first;
        }
    }
    cout << tot << endl;
}
int main(){
    ____();
    for(cin >> T; T; T--) solve();
    return 0;
}

\(I.Connected \Intervals\)

\(J.Triangle\ City\)

\(K.Happy\ Equation\)

\(L.Median\)

建大的向小的连边,同时建反图,如果图中存在环就直接全部输出0.
找每个点在拓扑排序序列中能够达到的最左端和最右端,如果\((n+1)/2\)在区间内的话,说明可以作为中位数,用bitset维护最少必经集合

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 111;
int T,n,m,deg[MAXN],rdeg[MAXN];
vector<int> G[MAXN],rG[MAXN];
bitset<MAXN> bst[MAXN],rbst[MAXN];
int toposort(){
    int tot = 0;
    queue<int> que;
    for(int i = 1; i <= n; i++) if(!deg[i]) que.push(i);
    while(!que.empty()){
        int u = que.front();
        que.pop();
        tot++;
        for(int v : G[u]){
            if(--deg[v]==0) que.push(v);
            bst[v] |= bst[u];
        }
    }
    return tot;
}
void rtoposort(){
    queue<int> que;
    for(int i = 1; i <= n; i++) if(!rdeg[i]) que.push(i);
    while(!que.empty()){
        int u = que.front();
        que.pop();
        for(int v : rG[u]){
            if(--rdeg[v]==0) que.push(v);
            rbst[v] |= rbst[u];
        }
    }
}
void init(){
    for(int i = 1; i <= n; i++){
        G[i].clear();
        rG[i].clear();
        rdeg[i] = 0;
        deg[i] = 0;
        bst[i].reset();
        bst[i].set(i);
        rbst[i].reset();
        rbst[i].set(i);
    }
}
void solve(){
    scanf("%d %d",&n,&m);
    init();
    for(int i = 1; i <= m; i++){
        int u, v;
        scanf("%d %d",&u,&v);
        G[u].emplace_back(v);
        rG[v].emplace_back(u);
        deg[v]++;
        rdeg[u]++;
    }
    int tot = toposort();
    if(tot!=n){
        for(int i = 0; i < n; i++) putchar('0');
        puts("");
        return;
    }
    rtoposort();
    for(int i = 1; i <= n; i++){
        int l = bst[i].count();
        int r = n-rbst[i].count()+1;
        if(l<=(n+1)/2 && (n+1)/2<=r) putchar('1');
        else putchar('0');
    }
    puts("");
}
int main(){
    for(scanf("%d",&T); T; T--) solve();
    return 0;
}

\(M. Sekiro\)

签到

include<bits/stdc++.h>

using namespace std;

define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)

const int N = 1e5+10;
int main(){
IOS;
int t; cin>>t;
while(t--){
int n,k; cin>>n>>k;
if(!n){
cout<<0<<endl;
continue;
}
while(k--){
if(n&1)n++;
n>>=1;
if(n==1)break;
}
cout<<n<<endl;
}
return 0;
}

原文地址:https://www.cnblogs.com/kikokiko/p/12274345.html

时间: 2024-10-02 01:19:36

The 10th Shandong Provincial Collegiate Programming Contest(8/13)的相关文章

(寒假开黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest(爽题)

layout: post title: (寒假开黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest(爽题) author: "luowentaoaa" catalog: true tags: mathjax: true - codeforces - DP - 状态压缩 - LCA 传送门 付队! C - Greetings! (状态压缩) 题意 给N种信件,你可以任意选择K种信封装信件,问你最少的浪费是多少 不能大的信件装

ZOJ 3703 Happy Programming Contest(0-1背包)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3703 Happy Programming Contest Time Limit: 2 Seconds      Memory Limit: 65536 KB In Zhejiang University Programming Contest, a team is called "couple team" if it consists of only two s

(寒假GYM开黑)2018 German Collegiate Programming Contest (GCPC 18)

layout: post title: 2018 German Collegiate Programming Contest (GCPC 18) author: "luowentaoaa" catalog: true tags: mathjax: true - codeforces 传送门 付队博客 C.Coolest Ski Route (记忆化搜索) 题意 给出一个有向图,求出一个权值最长的链, 题解 暴力dfs会超时,所以直接储存每个起点能走到的最远距离 #include<

(寒假GYM开黑)2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)

layout: post title: 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) author: "luowentaoaa" catalog: true tags: mathjax: true - codeforces 传送门 付队! B.Baby Bites (签到模拟) 按照题意模拟就行了 int a[maxn]; string s; int main() { std::ios::syn

(寒假开黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest

layout: post title: (寒假开黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest author: "luowentaoaa" catalog: true tags: mathjax: true - codeforces 传送门 付队! 许老师! Hello SCPC 2018! (签到) #include<bits/stdc++.h> using namespace std; typedef

(寒假开黑gym)2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017)

layout: post title: (寒假开黑gym)2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017) author: "luowentaoaa" catalog: true tags: mathjax: true - codeforces 传送门 付队! 许老师! B.Buildings (polya定理) 题意 B:给你m面墙,每面墙是n*n的格子,你有c种颜色,问你有多少种涂色方案.用po

ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2018) Syria, Lattakia, Tishreen University, April, 30, 2018

ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2018) Syria, Lattakia, Tishreen University, April, 30, 2018 Problem A. Can Shahhoud Solve it? Problem B. Defeat the Monsters Problem C. UCL Game Night Problem

ACM International Collegiate Programming Contest, JUST Collegiate Programming Contest (2018)

ACM International Collegiate Programming Contest, JUST Collegiate Programming Contest (2018) B. New Assignment 有n个人(1?≤?n?≤?104),有男有女,每个人都有一个id,现在这n个人分成学习互助小组,有三种组队模式,一个男人一组,一个女人一组,一男一女一组,如果要一男一女一组,那么这两人id的gcd要>1.保证任意三个人的gcd=1.求小组的组数最少是多少? 看起来是一个很裸的二

Nordic Collegiate Programming Contest 2015? B. Bell Ringing

Method ringing is used to ring bells in churches, particularly in England. Suppose there are 6 bells that have 6 different pitches. We assign the number 1 to the bell highest in pitch, 2 to the second highest, and so on. When the 6 bells are rung in