• Section 2.2


    Preface Numbering

    罗马数字的处理,问从1-N,各个IVX...什么的出现了多少次。

    我们可以用IVX表示出1-9

    XLC表示出10-90

    CDM表示出100-900

    统计出怎么出现的。接下来从高位往下减来表示就好了。

    #include <bits/stdc++.h>
    using namespace std;
    char dir[10] = {'I', 'V', 'X', 'L', 'C', 'D', 'M'};
    int cnt[10][3];
    int ans[10];
    void init(){
        int i;
        for(i = 1; i < 4; i++){
            cnt[i][0] = i;
        }
        cnt[4][0] = cnt[4][1] = 1;
        cnt[5][1] = 1;
        for(i = 6; i < 9; i++){
            cnt[i][0] = i-5; cnt[i][1] = 1;
        }
        cnt[9][0] = cnt[9][2] = 1;
    }
    
    void gao(int x, int base){
        for(int i = 0; i < 3; i++){
         //   cout<<x<<" " << cnt[x][i] <<endl;
            ans[base+i] += cnt[x][i];
        }
    }
    
    int main()
    {
        freopen("preface.in","r",stdin);
        #ifndef poi
        freopen("preface.out","w",stdout);
        #endif
        init();
        int n, i, j, x;
        cin >> n;
        for(i = 1; i <= n; i++){
            x = i;
            if(x >= 1000){
                ans[6] += x / 1000;
                x -= (x/1000)*1000;
            }
            if(x >= 100){
                gao(x/100, 4);
                x-= (x/100)*100;
            }
            if(x >= 10){
                gao(x/10, 2);
                x-= x/10*10;
            }
            if(x>0){
                //printf("!!%d
    ", x);
                gao(x, 0);
            }
        }
        for(i = 0 ; i <= 6; i++){
            if(ans[i]){
                cout << dir[i] <<" " << ans[i] <<endl;
            }
        }
        return 0;
    }
    View Code

    Subset Sums

    从1-N的数分成两块使得他们各自的和相等。N<=39

    可以算出所有的和。若为奇数,一定不能分成两块。

    否则算出每块和后简单的背包就好了。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 1005;
    ll dp[N];
    int main()
    {
        freopen("subset.in","r",stdin);
        #ifndef poi
        freopen("subset.out","w",stdout);
        #endif
        int n, i, j, m;
        cin >> n;
        dp[0] = 1;
        m = (n+1)*n/2;
        if(m&1) {
            cout << 0 <<endl;
            return 0;
        }
        m/=2;
        for(i = 1; i <= n; i++){
            for(j = m; j >= 0; j--){
                if(dp[j] && i + j <= m)   {
                    dp[j+i] += dp[j];
                }
            }
        }
        cout << dp[m] / 2<< endl;
    }
    View Code

    Runaround Numbers

    http://www.wzoi.org/usaco/12%5C205.asp 题意

    没想到怎么做,如果真要硬做的话估计就暴力一个个往上找。

    然而居然真的是这样。。。然而不知道怎么证明为什么一定可以找到一个。感觉程序还有不完善的地方,比如应该判断当大于几位数后就结束。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N  = 14;
    bool vis[N];
    char str[N];
    int len = 0;
    int go(int now, int step){
        step %= len;
        return (now - step + len) % len;
    }
    bool gao(int x){
        memset(vis, false, sizeof(vis));
        int tp = x, i, now; len = 0;
        while(tp){
            str[len++] = tp%10;
            if(vis[tp%10])return false;
            vis[tp%10] = true;
            tp /= 10;
        }
    
        memset(vis, false, sizeof(vis));
        now = 0;
        for(int k = 1; k < len; k++){
            vis[now] =true;
            now = go(now, str[now]);
            if(vis[now])    return false;
        }
        now = go(now, str[now]);
        if(now == 0)    return true;
        return false;
    
    }
    
    int main()
    {
        freopen("runround.in","r",stdin);
        #ifndef poi
        freopen("runround.out","w",stdout);
        #endif
        ll n;
        cin >> n;   n++;
        for(; ; n++){
           // cout << n << endl;
            if(gao(n))  break;
        }
        cout <<n <<endl;
        return 0;
    
    }
    View Code

    Party Lamps

    N盏灯(N<=100),一开始都是开着的。有4个开关,分别可以使:全部的灯,奇数号灯,偶数号灯,3* k+1号灯改变状态。一共操作C次

    给出某几盏灯必须是什么状态,求出所有的灯的状态的可能性。

     

    可以发现对一个开关开关两次后就相当于没有动过他,所以其实一共只有2^4中情况。其余的只要c-1的个数是偶数即可以让剩余操作抵消即可。

    所以暴力枚举16中情况。

    当没有可行状况要输出IMPOSSIBLE

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 34;
    const int M = 104;
    bool  ans[N][M], same[N][N];
    int n, c, id = 0;
    bool on[M], off[M];
    int f[N];
    
    void gao(int x){
        int one = 0, tp = x, i;
        while(tp){
            one += (tp&1);
            tp >>= 1;
        }
        if(c - one < 0 || ((c - one)&1))    return;
       // printf("%d
    ", x);
        ++id;
        for(i = 1; i <= n; i++) ans[id][i] = 1;
        if(x&1) for(i = 1; i <= n; i++) ans[id][i] ^= 1;
        if(x&2) for(i = 1; i <= n; i += 2) ans[id][i] ^= 1;
        if(x&4) for(i = 2; i <= n; i+= 2)   ans[id][i] ^= 1;
        if(x&8) for(i = 1; i <= n; i+= 3)   ans[id][i] ^= 1;
        //f[id] = id;
        for(i = 1; i <= n; i++){
          //  printf("%d %d
    ", i, ans[id][i]);
            if(on[i]&& !ans[id][i]){
                id --;  return;
            }
            if(off[i]&&ans[id][i]){
                id--;   break;
            }
        }
    
    }
    
    bool mor(int j, int k){
        int i;
    
        for(i = 1; i <= n; i++){
            if(ans[j][i] > ans[k][i]) return true;
            if(ans[j][i] < ans[k][i]) return false;
        }
        same[j][k] = same[k][j] = true;
    
    }
    int main()
    {
        freopen("lamps.in","r",stdin);
        #ifndef poi
        freopen("lamps.out","w",stdout);
        #endif
        int i, j, t;
        cin >> n >> c;
        while(cin >> t){
            if(t == -1) break;
            on[t] = true;
        }while(cin>>t){
            if(t == -1) break;
            off[t] = true;
        }
        int limit = (1<<4);
        for(i = 0; i < limit; i++){
            //printf("%d
    ", i);
            gao(i);
        }
        for(i = 1; i <= id; i++)f[i] = i;
        for(i = 1; i <= id; i++){
            for(j = 1; j <= id-i; j++){
                if(mor(f[j], f[j+1])) swap(f[j], f[j+1]);
            }
        }
        for(i = 1; i <= id; i++){
            if(same[i][i-1])    continue;
            for(j = 1; j <= n; j++){
                printf("%d", ans[f[i]][j]);
            }
            printf("
    ");
        }
        if(id == 0) printf("IMPOSSIBLE
    ");
        return 0;
    
    }
    View Code

    优化:

    1.有开关奇数偶数=开关全部的灯,可以继续减少情况。

    2.所有的灯以6为一个循环。所以只用存6个的状态就好,这样去重也方便。

  • 相关阅读:
    eclipse 报错问题:java.lang.ClassNotFoundException:
    java 根据Url下载对应的文件到指定位置,读txt文件获取url
    from表单校验插件 validate 实例
    登录注册校验方式
    微信浏览器发送ajax请求执行多次解决方法
    波哥博客Url
    常用ajax样例
    学习笔记......
    学习笔记...
    学习笔记..
  • 原文地址:https://www.cnblogs.com/bbbbbq/p/4655959.html
Copyright © 2020-2023  润新知