随便拉的比赛 题解

1. HDU - 5914

意识到最贪心的保留最多饼干的方案是 1 2 3 5 8 13 21 ..... 一个斐波那契数列,任选两个筷子都成不了三角形

所以给的N每大于其中的一个数就意味着我们能多保留一个筷子,其余的都不要

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 110;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
int a[10] = {0,1,2,3,5,8,13,21};
int main(){
    int T; Sca(T);
    int Case = 1;
    while(T--){
        Sca(N);
        printf("Case #%d: ",Case++);
        int ans = 0;
        for(int i = 1; i <= 6 ; i ++){
            if(N >= a[i]) ans++;
        }
        Pri(N - ans);
    } 
    return 0;
}
A

B.HDU - 6294

标题写着后缀数组但是并不

很显然最后一个是 > 还是 < 可以直接判断出来,然后从前往后判断,如果前一个字母比后一个大就是 > ,小就是 < ,如果相同的话就相当于两个字符串都去掉第一位比较,直接取上一个答案即可。

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
char str[maxn];
char ans[maxn];
int main(){
    int T; Sca(T);
    while(T--){
        Sca(N); scanf("%s",str + 1);
        if(str[N - 1] < str[N]) ans[N - 1] = '<';
        else ans[N - 1] = '>';
        for(int i = N - 2; i >= 1; i --){
            if(str[i] < str[i + 1]) ans[i] = '<';
            else if(str[i] > str[i + 1]) ans[i] = '>';
            else ans[i] = ans[i + 1];
        }
        ans[N] = '';
        printf("%s
",ans + 1);
    } 
    return 0;
}
B

C.HDU - 2203

A串(倍增)成两倍然后KMP找B串就可以了。

1.看了下提交似乎string.find()和strstr()直接调用也能过

2.按理来说需要特判A的长度比B的长度小的情况,不然出现A(ab),B(abab)的情况会算对,不特判就过了有可能是数据水

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 100000 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
char A[maxn * 2],B[maxn];
int Next[maxn];
void kmp_pre(char x[],int m,int nxt[]){
    int j = 0;
    nxt[1] = 0;
    for(int i = 2; i <= m ; i ++){
        while(j && x[i] != x[j + 1]) j = nxt[j];
        if(x[j + 1] == x[i]) j++;
        nxt[i] = j;
    }
}
bool KMP(char x[],int m,char y[],int n){
    kmp_pre(x,m,Next);
    int j = 0;
    for(int i = 1; i <= n ; i ++){
        while(j > 0 && x[j + 1] != y[i]) j = Next[j];
        if(x[j + 1] == y[i]) j++;
        if(j == m) return 1;
    }
    return 0;
}
int main(){
    while(~scanf("%s%s",A + 1,B + 1)){
        int l1 = strlen(A + 1),l2 = strlen(B + 1);
        if(l1 < l2){
            puts("no");
            continue;
        }
        for(int i = l1 + 1; i <= l1 + l1; i ++){
            A[i] = A[i - l1]; 
        }
        if(KMP(B,l2,A,l1 + l1)) puts("yes");
        else puts("no");
    }
    return 0;
}
C

D.HDU - 5969

从高位向低位扫

如果两个数字的第一位不相同,那很显然大的取10000000,小的取011111111,或一下最优秀

如果相同的话,答案的这一位就取他们相同的这个位然后继续扫

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 110;
const int INF = 0x3f3f3f3f;
LL l,r;
int a[maxn],b[maxn],c[maxn];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%lld%lld",&l,&r);
        if(l == r){
            printf("%lld
",l);
            continue;
        }
        int cnt1 = 0,cnt2 = 0;
        LL x = r,t = l;
        while(x){
            a[cnt1++] = x & 1; 
            x >>= 1;
        }
        while(t){
            b[cnt2++] = t & 1;
            t >>= 1;
        }
        if(cnt1 > cnt2){
            LL h = 1;
            for(int i = 0; i < cnt1; i ++){
                h <<= 1;
            }
            h--;
            printf("%lld
",h);
        }else{
            int ans = 0;
            for(int i = cnt1 - 1; i >= 0; i --){
                if(ans) c[i] = 1;
                else if(a[i] == 0 && b[i] == 0)    c[i] = 0;
                else if(a[i] == 1 && b[i] == 1) c[i] = 1;
                else{
                    c[i] = 1;
                    ans = 1;
                }
            }
            LL h = 1;
            for(int i = cnt1 - 2; i >= 0; i --){
                if(c[i] == 1){
                    h = h * 2 + 1;
                }else{
                    h <<= 1;
                }
            }
            printf("%lld
",h); //ans
        }
    }
    return 0;
}
D

E.HDU - 6082

最暴力显然的做法是 对每个骑士搞一个完全背包

但是时间复杂度不过关 1e5 * 1e3 * 1e3 

发现骑士的防御力似乎只有10?(*^_^*),那就把防御力相同的骑士放在一起,然后求10个完全背包就可以了

时间复杂度10 * 1000 * 1000

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 1e5 + 10;
const int maxm = 1010;
const LL INF = 1e18;
const int mod = 1e9 + 7; 
int N,M,K;
PII attack[maxm];
PII boss[maxn];
vector<int>type[20];
LL dp[maxn];
int main(){
    while(~Sca2(N,M)){
        int MAXb = 0,MAXa = 0;
        for(int i = 0; i <= 10; i ++) type[i].clear();
        for(int i = 1; i <= N ; i ++){
            Sca2(boss[i].fi,boss[i].se);
            MAXb = max(MAXb,boss[i].se);
            type[boss[i].se].pb(i);
        } 
        for(int i = 1; i <= M; i ++){
            Sca2(attack[i].fi,attack[i].se);
            MAXa = max(MAXa,attack[i].se);
        }
        if(MAXa <= MAXb){
            puts("-1");
            continue;
        }
        LL ans = 0;
        for(int i = 0 ; i <= 10; i ++){
            for(int j = 1; j <= 1000; j ++) dp[j] = INF;
            dp[0] = 0;
            for(int j = 1; j <= M ; j ++){
                int x = attack[j].se - i,p = attack[j].fi;
                if(x <= 0) continue;
                for(int k = 0 ; k <= 1000; k ++){
                    if(k >= x) dp[k] = min(dp[k],dp[k - x] + p);
                    else dp[k] = min(dp[k],dp[0] + p);
                }
            }
            for(int j = 0 ; j < type[i].size(); j ++) ans += dp[boss[type[i][j]].fi];
        }
        Prl(ans);
    }
    return 0;
}
E

F.HDU - 6023 

反正就 模拟嘛 看代码

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 2010;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
int vis[maxn];
int main(){
    int T;Sca(T);
    while(T--){
        Sca2(N,M); Mem(vis,0);
        LL ans = 0,num = 0;
        for(int i = 1; i <= M ; i ++){
            int id,h,m; char op[5];
            scanf("%d%d:%d%s",&id,&h,&m,op);
            if(op[0] == 'A' && ~vis[id]){
                ans += h * 60 + m + vis[id] * 20;
                vis[id] = -1; num++;
            }else if(~vis[id]){
                vis[id]++;
            }
        }
        printf("%lld %lld
",num,ans);
    }
    return 0;
}
F

G.HDU - 5795

nim博弈套了一个分堆

把分成三堆的SG函数求出来

发现8的倍数和+1变成8的倍数的情况有所改动,其他不变,然后就直接nim博弈

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 110;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
int main(){
    int T;Sca(T);
    while(T--){
        LL ans = 0; Sca(N);
        while(N--){
            int x; Sca(x);
            if(!((x + 1) % 8)) x++;
            else if(!(x % 8)) x--;
            ans ^= x;
        }
        if(ans) puts("First player wins.");
        else puts("Second player wins.");
    }
    return 0;
}
G
原文地址:https://www.cnblogs.com/Hugh-Locke/p/11166602.html