SCU集训队第四次周赛

A题(hdu2600 war):

用数组记录标记即可,开始不知道是多组数据以为是Coderforces的题数wa,以后周赛还是都写成多数据吧也好调试,然而多数据就要多注意初始化了。罗大神一直挂在名字可能有多个单词。
我这种开数组模拟的方法如果数据再大点就会ML,最好把开始和结尾存到一个结构体数组中,以终点为标准来结构体排序(如果终点相同起点小的靠前),然后从数组的最右边开始扫,如果第一个数都终点小于边界直接数组b,否则输出扫到的第一个,起点大于上一个终点的情况,扫完了都没有就输出Badly!。

#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream> //hdu 1544,
using namespace std;
typedef long long int LL;
const int M = 6000000, INF = 0x3fffffff;
bool str[12000009];

int main(void) {
    int n , l, r;
    string s;
l1:   while(cin >> n) {
        cin >> l >> r;
        memset(str,0,sizeof(str));
        while(n--) {
            int a, b;
            cin >> a >> b ;
            while(getchar() != '\n');
            for(int i = a + M; i  <= b + M; i++) str[i] = 1;
        }
        for(int i = r + M; i >= l + M; i--) {
            if(!str[i]) {
                cout << i - M << endl;
                goto l1;
            }
        }
        cout << "Badly!" << endl;
    }
    return 0;
}

B题(Pasha Maximizes && Coderforces 435B && 贪心模拟):

贪心思路:从最高位开始,每一次操作尽可能把最高位的数字变得最大,一直到操作步数走完,或者数已经达到最大。
模拟题最容易遗漏一些情况导致wa,比赛的时候往往比较心急,应该先写好代码,再复查一遍再交。

#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream> //hdu 1544,
using namespace std;
typedef long long int LL;
const int M = 100009,INF = 0x3fffffff;

char str[21];
int n, p, k;

bool doit(void) {
    int log = 0, key = -1;
    for(int i = p; i <= min(n - 1, p + k); i++) {
        if(str[i] - '0' > key) {
            key = str[i] - '0';
            log = i;
        }
    }
    while(log > p) {
        swap(str[log], str[log-1]);
        log--;
        k--;
    }
    p++;
    if(k <= 0 || p >= n - 1) return false;
    else return true;
}

int main(void) {
    cin >> str >> k;
    n = strlen(str);
    while(true) if(!doit()) break;
    printf("%s\n", str);
    return 0;
}

C题(水模拟):

#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream> //hdu 1544,
using namespace std;
typedef long long int LL;
const int M = 100009,INF = 0x3fffffff;

int n, str[M];

int main(void) {
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> str[i];
    int first = 1, second  = 1, ok = 0, ans = 1;
    str[n + 1] =  INF;
    for(int i = 1; i <= n; i++) {
        if(str[i + 1] < str[i]) {
            first = i;
            for(; i <= n; i++) {
                if(str[i + 1] > str[i]){
                    second = i;
                    ok = 1;
                    goto l1;
                }
            }
        }
    }
l1: for(int i = first, j = second; i < j; i++, j--)
        swap(str[i], str[j]);
    for(int i = 1; i < n; i++) {
        if(str[i] > str[i+1]) ans = 0;
    }
    if(ans) cout << "yes" << endl << first << " " << second << endl;
    else cout << "no" << endl;
    return 0;
}

D题(Boredom && Codeforces 455 A && dp):

不知道比赛的时候哪里来的想法,竟然用map来存,这个又不需要查找,直接用数组存就好了。注意的是要用long long(读题的时候就该注意到这点)。
思路:用一个 a[M] 数组来记录,每个数对应的个数,然后类似于01背包来选择选或者不选当前物品,定义 dp[i] 为前i物品的最大价值,相当于加了一个限制条件的01背包,有以下转移方程:

if(a[n] - an[n - 1] > 1) dp[i] = dp[i - 1] + i * a[i];
else dp[i] = max(dp[i - 1], dp[i - 2] + i * a[i]);
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream> //hdu 1544,
using namespace std;
typedef long long int LL;
const int M = 100009,INF = 0x3fffffff;

int n;
map<LL, LL> m;
map<LL, LL>::iterator it,ite;
LL dp[M];

int main(void) {
    while(cin >> n) {
        m.clear();
        memset(dp,0,sizeof(dp));
        for(int i = 1; i <= n; i++) {
            LL x;
            cin >> x;
            if(m.count(x)) m[x]++;
            else m[x] = 1;
        }
        it = m.begin();
        int i;
        for(i = 3;it != m.end(); it++, i++) {
            ite=it;
            ite--;
            if((it -> first) - (ite -> first) > 1) dp[i] = dp[i - 1] + (it -> first) * (it -> second);
            else dp[i] = max(dp[i - 2] + (it -> first) * (it -> second), dp[i - 1]);
        }
        LL ans = 0;
        for(int i = 1; i < M; i++) if(dp[i] > ans) ans = dp[i];
        cout << ans << endl;
    }
    return 0;
}

E题(Little Pony and Sort by Shift && Codeforces 454B && 模拟):

简单题,只需找到那个唯一一个不满足要求的断点即可,如果这类型断点个数超过一个就没有办法,如果为0,直接输出,为1就看距离最右边的距离就是步数。

#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream> //hdu 1544,
using namespace std;
typedef long long int LL;
const int M = 100009,INF = 0x3fffffff;

int str[M], step, n;

int  ok(void) {
    int aa = 0;
    for(int i = 1; i <= n; i++) {
        int j = i + 1;
        if(j > n) j = 1;
        if(str[i] > str[j]) aa++;
        if(aa > 1) return aa;
    }
    return aa;
}

int main(void) {
    while(cin >> n) {
        for(int i = 1; i <= n; i++) {cin >> str[i]; str[n + i] = str[i];}
        int x = ok();
        if(!x) cout << x << endl;
        else if(x > 1) cout << -1 << endl;
        else {
            int i;
            for(i = 1; i <= n; i++) {
                int j = i + 1;
                if(j > n) j = 1;
                if(str[i] > str[j]) break;
            }
            cout << n - i << endl;
        }

    }
    return 0;
}

你可能感兴趣的:(SCU集训队第四次周赛)