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;
}

 

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