1. 程式人生 > 其它 >《Educational Codeforces Round 118 (Rated for Div. 2)》

《Educational Codeforces Round 118 (Rated for Div. 2)》

A題寫炸了。

A:一開始寫了個字串沒算複雜度T了,實際上從高到低判斷即可。

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double ld;
typedef pair<int,int> pii;
const int N = 1e5 + 5;
const int M = 1e6 + 5;
const LL Mod = 1e9 + 7;
#define rep(at,am,as) for(int at = am;at <= as;++at)
#define
ret(at,am,as) for(int at = am;at >= as;--at) #define INF 1e9 #define dbg(ax) cout << "now this num is " << ax << endl; inline long long ADD(long long x,long long y) { if(x + y < 0) return ((x + y) % Mod + Mod) % Mod; return (x + y) % Mod; } inline long long MUL(long long
x,long long y) { if(x * y < 0) return ((x * y) % Mod + Mod) % Mod; return x * y % Mod; } inline long long DEC(long long x,long long y) { if(x - y < 0) return (x - y + Mod) % Mod; return (x - y) % Mod; } int a[N],b[N]; int len(int x) { int len = 0; while(x != 0) a[++len] = x % 10
,x /= 10; reverse(a + 1,a + len + 1); return len; } int glen2(int x) { int len = 0; while(x != 0) b[++len] = x % 10,x /= 10; reverse(b + 1,b + len + 1); return len; } void solve() { int x,p;cin >> x >> p; int x2,p2;cin >> x2 >> p2; int le1 = len(x),le2 = glen2(x2); int len1 = le1 + p,len2 = le2 + p2; if(len1 > len2) printf(">\n"); else if(len1 < len2) printf("<\n"); else { if(le1 == le2) { if(x == x2) printf("=\n"); else printf("%c\n",x > x2 ? '>' : '<'); } else if(le1 > le2) { int f = 0; for(int i = 1;i <= min(le1,le2);++i) { if(a[i] > b[i]) {f = 1;printf(">\n");break;} else if(a[i] < b[i]) {f = 1;printf("<\n");break;} } if(f == 0) { int ff = 0; for(int i = le2 + 1;i <= le1;++i) if(a[i] != 0) {ff = 1;} printf("%c\n",ff ? '>' : '='); } } else { int f = 0; for(int i = 1;i <= min(le1,le2);++i) { if(a[i] > b[i]) {f = 1;printf(">\n");break;} else if(a[i] < b[i]) {f = 1;printf("<\n");break;} } if(f == 0) { int ff = 0; for(int i = le1 + 1;i <= le2;++i) if(b[i] != 0) {ff = 1;} printf("%c\n",ff ? '<' : '='); } } } } int main() { int _; for(scanf("%d",&_);_;_--) { solve(); } // system("pause"); return 0; }
View Code

B:每個數和最小的操作必定 < 最小的

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double ld;
typedef pair<int,int> pii;
const int N = 2e5 + 5;
const int M = 1e6 + 5;
const LL Mod = 1e9 + 7;
#define rep(at,am,as) for(int at = am;at <= as;++at)
#define ret(at,am,as) for(int at = am;at >= as;--at)
#define INF 1e9
#define dbg(ax) cout << "now this num is " << ax << endl;
inline long long ADD(long long x,long long y) {
    if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
    return (x + y) % Mod;
}
inline long long MUL(long long x,long long y) {
    if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
    return x * y % Mod;
}
inline long long DEC(long long x,long long y) {
    if(x - y < 0) return (x - y + Mod) % Mod;
    return (x - y) % Mod;
}

int a[N];
vector<pii> ans;
int pos[M];
void solve() {
    int n;scanf("%d",&n);
    rep(i,1,n) scanf("%d",&a[i]),pos[a[i]] = i;
    int up = n / 2;
    sort(a + 1,a + n + 1);
    for(int i = 2;i <= up + 1;++i) printf("%d %d\n",a[i],a[1]);
}   
int main() {
    int _;
    for(scanf("%d",&_);_;_--) {
        solve();
    }
    //system("pause");
    return 0;
}
View Code

C:比較經典的二分了

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double ld;
typedef pair<int,int> pii;
const int N = 2e5 + 5;
const int M = 1e6 + 5;
const LL Mod = 1e9 + 7;
#define rep(at,am,as) for(int at = am;at <= as;++at)
#define ret(at,am,as) for(int at = am;at >= as;--at)
#define INF 1e9
#define dbg(ax) cout << "now this num is " << ax << endl;
inline long long ADD(long long x,long long y) {
    if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
    return (x + y) % Mod;
}
inline long long MUL(long long x,long long y) {
    if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
    return x * y % Mod;
}
inline long long DEC(long long x,long long y) {
    if(x - y < 0) return (x - y + Mod) % Mod;
    return (x - y) % Mod;
}

int n,a[N];
LL h;
bool check(LL x) {
    LL r = a[1] + x - 1,de = 0;
    for(int i = 2;i <= n;++i) {
        if(a[i] > r) de += x;
        else de += a[i] - a[i - 1];
        r = a[i] + x - 1;
    }
    de += x;
   // printf("x is %lld de is %lld\n",x,de);
    return de >= h;
}
void solve() {
    scanf("%d %lld",&n,&h);
    rep(i,1,n) scanf("%d",&a[i]);
    LL L = 1,r = h,ans = h;
    while(L <= r) {
        LL mid = (L + r) >> 1;
        if(check(mid)) ans = mid,r = mid - 1;
        else L = mid + 1;
    }
    printf("%lld\n",ans);
}   
int main() {
    int _;
    for(scanf("%d",&_);_;_--) {
        solve();
    }
    //system("pause");
    return 0;
}
View Code

D:這題比E要難挺多感覺。

一開始推了個錯的dp。

首先,我們需要對序列進行判斷,假設當前為111 222 333.

那麼這時候我們在序列後面 + 4 = 111 222 333 4 - 保持上升序列

+ 1,2顯然都不合法,+ 5滿足這時序列變為111 222 333 5。

當序列為111 222 333 5時,我們在尾部能加得元素就只有3,5其他加入都不滿足。

所以我們插入的序列一定是一個上序序列或者斷開過一截的上升序列。

考慮dp解決。

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double ld;
typedef pair<int,int> pii;
const int N = 5e5 + 5;
const int M = 1e6 + 5;
const LL Mod = 998244353;
#define rep(at,am,as) for(int at = am;at <= as;++at)
#define ret(at,am,as) for(int at = am;at >= as;--at)
#define INF 1e9
#define dbg(ax) cout << "now this num is " << ax << endl;
inline long long ADD(long long x,long long y) {
    if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
    return (x + y) % Mod;
}
inline long long MUL(long long x,long long y) {
    if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
    return x * y % Mod;
}
inline long long DEC(long long x,long long y) {
    if(x - y < 0) return (x - y + Mod) % Mod;
    return (x - y) % Mod;
}

int n;
LL dp[N][3],tmp[3];//0 - i作為最大值且沒有斷裂,1 - i作為最大值發生斷裂,2 - i作為次大值發生斷裂
void solve() {
    scanf("%d",&n);
    rep(i,0,n + 2) rep(j,0,2) dp[i][j] = 0;
    rep(i,1,n) {
        int x;scanf("%d",&x);
        memset(tmp,0,sizeof(tmp));
        tmp[0] = dp[x][0];
        if(x > 0) tmp[0] = ADD(tmp[0],dp[x - 1][0]);
        else tmp[0] = ADD(tmp[0],1);
        
        tmp[1] = ADD(tmp[1],dp[x][1]);
        if(x > 1) tmp[1] = ADD(tmp[1],ADD(dp[x - 2][0],dp[x - 2][2]));
        else if(x == 1) tmp[1] = ADD(tmp[1],1);

        tmp[2] = ADD(tmp[2],dp[x][2]);
        tmp[2] = ADD(tmp[2],dp[x + 2][1]);
        dp[x][0] = ADD(dp[x][0],tmp[0]);
        dp[x][1] = ADD(dp[x][1],tmp[1]);
        dp[x][2] = ADD(dp[x][2],tmp[2]);
      //  printf("in %d dp[0] is %lld dp[1] is %lld d[2] is %lld\n",i,tmp[0],tmp[1],tmp[2]);
    }
    LL ans = 0;
    rep(i,0,n) rep(j,0,2) {
        //if(dp[i][j] != 0) printf("dp[%d][%d] is %lld\n",i,j,dp[i][j]);
        ans = ADD(ans,dp[i][j]);
    }
    printf("%lld\n",ans);
}   
int main() {
    int _;
    for(scanf("%d",&_);_;_--) {
        solve();
    }
   // system("pause");
    return 0;
}
/*
30
7
1 3 2 3 0 0 1
9
3 1 2 1 0 2 0 3 0
*/
View Code

E:

這題其實不難,很顯然從L開始搜,這時我們會遇到一個情況,它處於可以走到L的一個塊的旁邊,但是現在我們去判斷。

這個塊還不能走到L,其實我們並不需要管,因為當這個塊能走到L時,肯定會被它旁邊另外一個新的能走到L的更新成功。

所以一次bfs就能解決問題。

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double ld;
typedef pair<char,int> pii;
const int N = 1e6 + 5;
const int M = 1e6 + 5;
const LL Mod = 998244353;
#define rep(at,am,as) for(int at = am;at <= as;++at)
#define ret(at,am,as) for(int at = am;at >= as;--at)
#define INF 1e9
#define dbg(ax) cout << "now this num is " << ax << endl;
inline long long ADD(long long x,long long y) {
    if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
    return (x + y) % Mod;
}
inline long long MUL(long long x,long long y) {
    if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
    return x * y % Mod;
}
inline long long DEC(long long x,long long y) {
    if(x - y < 0) return (x - y + Mod) % Mod;
    return (x - y) % Mod;
}

vector<pii> vec[N];
int n,m,d[4][2] = {1,0,-1,0,0,1,0,-1};
bool ishav(int i,int j) {
    if(i >= 0 && i < n && j >= 0 && j < m && vec[i][j].first != '#' && vec[i][j].second != 1) return true;
    else return false; 
}
bool check(int i,int j) {
    if(i >= 0 && i < n && j >= 0 && j < m && vec[i][j].first == '.' && vec[i][j].second != 1) return true;
    else return false; 
}
struct Node{int x,y;};
void bfs(int x,int y) {
    queue<Node> Q;
    vec[x][y].second = 1;
    Q.push(Node{x,y});
    while(!Q.empty()) {
        Node q = Q.front();
        Q.pop();
        rep(i,0,3) {
            int px = q.x + d[i][0],py = q.y + d[i][1];
            if(ishav(px,py)) {
                int cnt = 0;
                rep(j,0,3) if(check(px + d[j][0],py + d[j][1])) cnt++;
               // printf("px is %d py is %d cnt is %d\n",px,py,cnt);
                if(cnt <= 1) {
                    vec[px][py].second = 1;
                    Q.push(Node{px,py});
                }
            }
        }
    }
}
void solve() {
    scanf("%d %d",&n,&m);
    int edi,edj;
    rep(i,0,n - 1) {
        string s;cin >> s;
        rep(j,0,m - 1) {
            if(s[j] == 'L') edi = i,edj = j;
            vec[i].push_back(pii{s[j],0});
        }
    }
    bfs(edi,edj);
    rep(i,0,n - 1) {
        rep(j,0,m - 1) {
            if(vec[i][j].second != 1 || vec[i][j].first == 'L') printf("%c",vec[i][j].first);
            else printf("+");
        }
        printf("\n");
    }
    rep(i,0,n - 1) vec[i].clear();
}   
int main() {
    int _;
    for(scanf("%d",&_);_;_--) {
        solve();
    }
 //   system("pause");
    return 0;
}
View Code