Codeforces Round #551 (Div. 2)

A:https://codeforces.com/contest/1153/problem/A

題意:有n種班車,已知各種班車的第一班車的時刻以及各個班車的間隔時間,有個小朋友在t時刻到達,他想要儘快上車,無論那種班次都行。問他最終上的是哪一種班車。

思路:水題,對每一種班車,找出這個小朋友最早上車的時刻,那麼對於每一種班車,都會有個最早上車的時刻。在這n個時刻中,取其中最小值即可。

代碼:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#define Fin             freopen("in.txt","r",stdin)
#define Fout            freopen("out.txt","w",stdout)
#define Case(T)         int T;for(scanf("%d",&T);T--;)
#define fo(i,a,b)              for(int i = a; i < b; ++i)
#define fd(i,a,b)              for(int i = a; i >= b; --i)
#define me(a,b) memset(a,b,sizeof(a))
#define fi(a,n,val)    fill(a,a+n,val)
#define Scand(n)	   scanf("%d",&n)
#define Scand2(a,b)     scanf("%d%d",&a,&b)
#define Scand3(a,b,c)     scanf("%d%d%d",&a,&b,&c)
#define Scand4(a,b,c,d)     scanf("%d%d%d%d",&a,&b,&c,&d)
#define Scans(s)	   scanf("%s",s)
#define random(a,b)    a+rand()%(b-a+1)
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b ? gcd(b,a%b): a; }
const int maxn = 105;
const int INFint = 0xffffff;
const ll INFll = (ll)1e18;

#ifndef ONLINE_JUDGE

#endif // ONLINE_JUDGE

inline int readint(){
    int sgn = 1; int sum = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if(ch == '-')   sgn = -sgn;
        ch = getchar();
    }
    while ('0' <= ch && ch <= '9') {
        sum = sum*10+(ch-'0');
        ch = getchar();
    }
    return sgn*sum;
}

inline ll readll(){
    ll sgn = 1; ll sum = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if(ch == '-')   sgn = -sgn;
        ch = getchar();
    }
    while ('0' <= ch && ch <= '9') {
        sum = sum*10+(ch-'0');
        ch = getchar();
    }
    return sgn*sum;
}

int n, t;
int a[maxn], b[maxn];

int main()
{
	#ifndef ONLINE_JUDGE
		//Fin;
    #endif // ONLINE_JUDGE
    cin >> n >> t;
    for(int i = 0; i < n; ++i){
        cin >> a[i] >> b[i];
    }
    int ans = INFint;
    int ansIndex = -1;
    for(int i = 0; i < n; ++i){
        while(1){
            if(a[i] >= t){
                if(a[i] < ans){
                    ans = a[i];
                    ansIndex = i;
                }
                break;
            }
            a[i] += b[i];
        }
    }
    cout << ansIndex+1;
    return 0;
}

B:https://codeforces.com/contest/1153/problem/B

題意:給你一個積木的三視圖:正視圖(一維數組表示,其中數組值爲該列中的最高那行積木的高度),左視圖(一維數組表示,其中數組值爲該行最高那列積木的高度),俯視圖(二維數組,其中數組值:爲1,表示有積木,爲0,表示沒有積木)。要求還原積木的具體圖形,用俯視圖表示(二維數組,數組值表示那個格子上有多少個積木,即高度)。存在多種答案,輸出其中任意一種即可。

思路:從俯視圖入手,忽略數組值爲0的格子,對於數組值爲1的格子,從該列的主視圖和該行的左視圖可以得到這個格子高度的兩個上限值,取這兩個上限值的最小值作爲該格子的高度。

代碼:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#define Fin             freopen("in.txt","r",stdin)
#define Fout            freopen("out.txt","w",stdout)
#define Case(T)         int T;for(scanf("%d",&T);T--;)
#define fo(i,a,b)              for(int i = a; i < b; ++i)
#define fd(i,a,b)              for(int i = a; i >= b; --i)
#define me(a,b) memset(a,b,sizeof(a))
#define fi(a,n,val)    fill(a,a+n,val)
#define Scand(n)	   scanf("%d",&n)
#define Scand2(a,b)     scanf("%d%d",&a,&b)
#define Scand3(a,b,c)     scanf("%d%d%d",&a,&b,&c)
#define Scand4(a,b,c,d)     scanf("%d%d%d%d",&a,&b,&c,&d)
#define Scans(s)	   scanf("%s",s)
#define random(a,b)    a+rand()%(b-a+1)
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b ? gcd(b,a%b): a; }
const int maxn = 105;
const int INFint = 0xffffff;
const ll INFll = (ll)1e18;

#ifndef ONLINE_JUDGE

#endif // ONLINE_JUDGE

inline int readint(){
    int sgn = 1; int sum = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if(ch == '-')   sgn = -sgn;
        ch = getchar();
    }
    while ('0' <= ch && ch <= '9') {
        sum = sum*10+(ch-'0');
        ch = getchar();
    }
    return sgn*sum;
}

inline ll readll(){
    ll sgn = 1; ll sum = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if(ch == '-')   sgn = -sgn;
        ch = getchar();
    }
    while ('0' <= ch && ch <= '9') {
        sum = sum*10+(ch-'0');
        ch = getchar();
    }
    return sgn*sum;
}

int n,m,h;
int a[maxn];
int b[maxn];
int c[maxn][maxn];
int ans[maxn][maxn];

int main()
{
	#ifndef ONLINE_JUDGE
		//Fin;
	#endif // ONLINE_JUDGE
    cin >> n >> m >> h;
    for(int i = 1; i <= m; ++i)
        cin >> a[i];
    for(int i = 1; i <= n; ++i)
        cin >> b[i];
    for(int i = 1; i <= n; ++i){
        for(int j = 1; j <= m; ++j){
            cin >> c[i][j];
        }
    }
    for(int i = 1; i <= n; ++i){
        for(int j = 1; j <= m; ++j){
            if(c[i][j]){
            	//printf("i:%d j:%d a:%d b:%d\n", i, j, a[i], b[j]);
                int tmp = INFint;
                tmp = min(tmp, a[j]);
                tmp = min(tmp, b[i]);
                ans[i][j] = tmp;
            }
        }
    }
    for(int i = 1; i <= n; ++i){
        for(int j = 1; j <= m; ++j){
            if(j != 1)
                cout << ' ';
            cout << ans[i][j];
        }
        cout << endl;
    }
	return 0;
}

C:https://codeforces.com/contest/1153/problem/C

題意:給你一個長度爲n的字符串,只包含'('、')'、'?'。對'?'進行填充'('或者')',要求填充完畢的字符串:① 除去最後一個字符,該字符串的括號無法完全匹配 ② 加上最後那個字符,該字符串的括號剛好完全匹配。

思路:將'('轉爲1,將')'轉爲-1,然後對字符串遍歷一遍,設置sum = 0,進行累加,對於符合題目要求的字符串,應該滿足:① 除去最後那個字符,在遍歷過程中,sum應該始終>=0 ② 遍歷完成後,sum應該剛好=0

基於這種要求,填充'?’時可以採取貪心策略,開始儘可能使sum大,這樣sum纔會始終保持在0之上。這樣的話,開始時,儘可能使'?'匹配爲'(',這樣sum會加1.

總結:這種方法很巧妙,對於括號匹配問題,該方法具有一般性:將'('轉爲1,將')'轉爲-1,初始sum=0,遍歷字符串,累加到sum中

① 當sum < 0 =》該字符串不可能會完全匹配

② 當sum > 0 =》該字符串有可能會完全匹配(添加')')

③ 當sum = 0 =》 截止到sum=0時的下標時,字符串剛好完全匹配

代碼:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#define Fin             freopen("in.txt","r",stdin)
#define Fout            freopen("out.txt","w",stdout)
#define Case(T)         int T;for(scanf("%d",&T);T--;)
#define fo(i,a,b)              for(int i = a; i < b; ++i)
#define fd(i,a,b)              for(int i = a; i >= b; --i)
#define me(a,b) memset(a,b,sizeof(a))
#define fi(a,n,val)    fill(a,a+n,val)
#define Scand(n)       scanf("%d",&n)
#define Scand2(a,b)     scanf("%d%d",&a,&b)
#define Scand3(a,b,c)     scanf("%d%d%d",&a,&b,&c)
#define Scand4(a,b,c,d)     scanf("%d%d%d%d",&a,&b,&c,&d)
#define Scans(s)       scanf("%s",s)
#define random(a,b)    a+rand()%(b-a+1)
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b ? gcd(b,a%b): a; }
const int maxn = 1e4 + 50;
const int INFint = 0xffffff;
const ll INFll = (ll)1e18;

#ifndef ONLINE_JUDGE

#endif // ONLINE_JUDGE

inline int readint(){
    int sgn = 1; int sum = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if(ch == '-')   sgn = -sgn;
        ch = getchar();
    }
    while ('0' <= ch && ch <= '9') {
        sum = sum*10+(ch-'0');
        ch = getchar();
    }
    return sgn*sum;
}

inline ll readll(){
    ll sgn = 1; ll sum = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if(ch == '-')   sgn = -sgn;
        ch = getchar();
    }
    while ('0' <= ch && ch <= '9') {
        sum = sum*10+(ch-'0');
        ch = getchar();
    }
    return sgn*sum;
}

int n;
string s;

void input(){
    cin >> n >>  s;
}

void output(){
    printf("n:%d\n", n);
    cout << "s:" << s << endl;
}

void solve(){
    int cnt1 = 0;
    int cnt2 = 0;
    for(int i = 0; i < n; ++i){
        if(s[i] == '(')
            cnt1++;
        if(s[i] == ')')
            cnt2++;
    }
    int sum = 0;
    for(int i = 0; i < n; ++i){
        if(s[i] == '('){
            sum += 1;
        }else if(s[i] == ')'){
            sum += -1;
        }else if(s[i] == '?'){
            if(cnt1 < n/2){
                sum += 1;
                cnt1++;
                s[i] = '(';
            }else{
                sum += -1;
                s[i] = ')';
            }
        }
        if(i != n-1 && sum <= 0){
            // printf("i:%d\n", i);
            cout << ":(" << endl;
            return ;
        }
    }
    if(sum != 0){
        // cout << s << endl;
        //printf("last failed!\n");
        cout << ":(" << endl;
        return ;
    }
    cout << s << endl;
    return ;
}

int main()
{
    #ifndef ONLINE_JUDGE
        //Fin;
    #endif // ONLINE_JUDGE
    input();
    // output();
    solve();
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章