zoukankan      html  css  js  c++  java
  • 寒假训练4解题报告

    1.   CodeForces 222B     Cosmic Tables

    数据量比较大,这里不能直接暴力,用行指针和列指针表示当前行列是原来的第几行第几列

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    const int N = 1005;
    int n ,m , k , row[N] , col[N] , a[N][N];
    char s[5] ;
    int p1 , p2;
    int main()
    {
      //  freopen("a.in" , "r" , stdin);
        while(scanf("%d%d%d" , &n , &m , &k) == 3)
        {
            for(int i=1 ; i<=n ; i++)
                for(int j =1 ; j<=m ; j++)
                    scanf("%d" , &a[i][j]);
            int maxn = max(n , m);
            for(int i=1; i<=maxn ; i++)
                row[i] = i , col[i] = i;
            for(int i=1 ; i<=k ; i++){
                scanf("%s%d%d" , s , &p1 , &p2);
                if(s[0] == 'g') printf("%d
    " , a[row[p1]][col[p2]]);
                else if(s[0] == 'c'){
                    int t = col[p1];
                    col[p1] = col[p2] , col[p2] = t;
                }
                else{
                    int t = row[p1];
                    row[p1] = row[p2] , row[p2] = t;
                }
            }
        }
        return 0;
    }
    View Code

    2. CodeForces 222C   Reducing Fractions

    先打表记录10^7内的所有素因子

    题目比较简单,但过程写的有点长,记录a数组中总共包含了多少的素因子,并记录其个数

    然后根据这个个数不断将b[]中的元素消去以最大可能消去这些因子,但不超过a[]中所记录的因子数,并记录消去的因子数,说明这些数目的因子在a[]中也存在这么多

    然后再返回将a[]中的元素也消去这么多因子

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <cmath>
      5 using namespace std;
      6 const int N = 100005;
      7 const int maxn = 10000000;
      8 int a[N] , b[N];
      9 bool vis[maxn];
     10 int prime[maxn/10] , k , cnt[maxn/10] , del[maxn/10];
     11 
     12 void get_prime()
     13 {
     14     k=0;
     15     memset(vis , 0 , sizeof(vis));
     16     for(int i=2 ; i<maxn ; i++){
     17         if(!vis[i]){
     18             prime[k++] = i;
     19             for(int j=i+i ; j<maxn ; j+=i) vis[j] = true;
     20         }
     21     }
     22 }
     23 
     24 int bin_seach(int x)
     25 {
     26     int l=0 , r = k-1;
     27     while(l<=r){
     28         int m = (l+r)>>1;
     29         if(prime[m] == x) return m;
     30         else if(prime[m] > x) r = m-1;
     31         else l=m+1;
     32     }
     33 }
     34 
     35 void get_factor(int x)
     36 {
     37     int t = (int)sqrt(x+0.5);
     38     for(int i=0 ; i<k ; i++){
     39         if(prime[i]*prime[i] > x) break;
     40         if(x % prime[i] == 0){
     41             while(x % prime[i] == 0)
     42             {
     43                 x /= prime[i];
     44                 cnt[i]++;
     45             }
     46         }
     47     }
     48     if(x>1) cnt[bin_seach(x)]++;
     49 }
     50 
     51 int del_factor(int x)
     52 {
     53     int m = x;
     54     int t = (int)sqrt(x+0.5);
     55     for(int i=0 ; i<k ; i++){
     56         if(prime[i]*prime[i] > x) break;
     57         if(x % prime[i] == 0){
     58             while(x % prime[i] == 0)
     59             {
     60                 if(cnt[i]) m/=prime[i] , cnt[i]--,del[i]++;
     61                 x /= prime[i];
     62             }
     63         }
     64     }
     65     if(x>1){
     66         int pos = bin_seach(x);
     67         if(cnt[pos]) m/=prime[pos] , cnt[pos]--,del[pos]++;
     68     }
     69     return m;
     70 }
     71 
     72 int get_a(int x)
     73 {
     74     int m = x;
     75     int t = (int)sqrt(x+0.5);
     76     for(int i=0 ; i<k ; i++){
     77         if(prime[i]*prime[i] > x) break;
     78         if(x % prime[i] == 0){
     79             while(x % prime[i] == 0)
     80             {
     81                 if(del[i]) m/=prime[i] ,del[i]--;
     82                 x /= prime[i];
     83             }
     84         }
     85     }
     86     if(x>1){
     87         int pos = bin_seach(x);
     88         if(del[pos]) m/=prime[pos] , del[pos]--;
     89     }
     90     return m;
     91 }
     92 
     93 int main()
     94 {
     95    // freopen("a.in" , "r" , stdin);
     96     get_prime();
     97     int n,m;
     98     while(scanf("%d%d" , &n , &m) == 2)
     99     {
    100         memset(cnt , 0 , sizeof(cnt));
    101         for(int i=0 ; i<n ; i++)
    102         {
    103             scanf("%d" , a+i);
    104             get_factor(a[i]);
    105         }
    106         memset(del , 0 , sizeof(del));
    107         for(int i=0 ; i<m ; i++)
    108         {
    109             scanf("%d" , b+i);
    110             int tmp = b[i];
    111             b[i] = del_factor(tmp);
    112         }
    113 
    114         for(int i=0 ; i<n ; i++)
    115         {
    116             int tmp = a[i];
    117             a[i] = get_a(tmp);
    118         }
    119         printf("%d %d
    " , n , m);
    120         for(int i=0 ; i<n ; i++){
    121             if(i == 0) printf("%d" , a[i]);
    122             else printf(" %d" , a[i]);
    123         }
    124         puts("");
    125         for(int i=0 ; i<m ; i++){
    126             if(i == 0) printf("%d" , b[i]);
    127             else printf(" %d" , b[i]);
    128         }
    129         puts("");
    130     }
    131     return 0;
    132 }
    View Code

    3.  CodeForces 222D   Olympiad

    一道简单的贪心,最好情况必然为第一名,最差情况,可以先排序,a[] 由小到大, b[]由大到小,每次取尽可能多的成立的组,然后让其作为所有组的最后一名即可

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int N = 100005;
    int a[N] , b[N] , sum[N] , vis[N];
    
    bool cmp(int a , int b)
    {
        return a>b;
    }
    int main()
    {
       // freopen("a.in" , "r" , stdin);
        int n , k;
        while(scanf("%d%d" , &n , &k) == 2)
        {
            for(int i=0 ; i<n ; i++)
                scanf("%d", a+i);
            sort(a , a+n);
            for(int i=0 ; i<n ; i++)
                scanf("%d", b+i);
            sort(b , b+n , cmp);
            memset(vis , 0 , sizeof(vis));
            int ans=0 , flag = 0;
            int index = 0 ;
            for(int i=0 ; i<n ; i++)
            {
                while(b[i]+a[index]<k || vis[index]){
                    if(index == n-1){flag = 1 ;break;}
                    index  = (index+1)%n;
                }
                if(flag) break;
                vis[index]=1;
                ans++;
                index = (index+1)%n;
            }
    
            printf("%d %d
    " , 1 , ans);
        }
        return 0;
    }
    View Code

    4.CodeForces 271D Good Substrings

    用字典树记录已存在的字符串,但不要傻傻的添加字符串时都从root开始,因为我们都是从某一点出发,每次往后多添加一个字符,所以第一层循环中可以每次都保留当前访问到的字典树的位置,从这个位置向下一格就好,否则会超时

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int N = 1600;
    char s1[N] , s2[N];
    int sum[N] , k;
    bool good[N];
    
    struct Node{
        Node *next[26];
        int flag;
        Node(){
            flag = 0;
            for(int i=0 ; i<26 ; i++)
                next[i] = NULL;
        }
    };
    
    Node *root;
    Node *cur;
    
    void add_string(int i , int &ans)
    {
        int id = s1[i]-'a';
        if(cur->next[id] == NULL) cur->next[id] = new Node();
        cur = cur->next[id];
    
        if(cur->flag == 0)
            ans++;
    
        cur->flag = 1;
    }
    
    int main()
    {
       // freopen("a.in" , "r" , stdin);
        int  k;
        while(scanf("%s" , s1+1) == 1)
        {
            scanf("%s%d" , s2 , &k);
            for(int i=0 ; i<26 ; i++)
                good[i] = s2[i] == '1';
            int len = strlen(s1+1);
            for(int i=1 ; i<=len ; i++){
                sum[i] = sum[i-1];
                if(!good[s1[i]-'a']) sum[i]++;
            }
            root = new Node();
            int ans = 0;
            for(int l=1 ; l<=len ; l++){
                cur = root;
                for(int r=l ; r<=len ; r++){
                    if(sum[r] - sum[l-1] <= k) add_string(r,ans);
                }
            }
            printf("%d
    " , ans);
        }
        return 0;
    }
    View Code

    5.  CodeForces 222E Decoding Genome

    一道dp题目,开始想到了要dp,不过一看n的取值就放弃dp了,不得不说自己很傻

    当n值很大总应想到logn解决问题的矩阵快速幂

    dp[i][c] 表示前 i 个字符,以 字符c结尾的种数 , 这里 c 有 m 种,所以用 m*m的矩阵进行快速幂即可

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    #define ll long long
    const int N = 1<<6;
    const int MOD = 1000000007;
    int dp[30],m,k;
    ll n;
    char s[4];
    
    struct Matrix{
        ll mat[52][52];
        Matrix operator*(const Matrix &p)const{
            Matrix ans;
            for(int i=0 ; i<m ; i++){
                for(int j=0 ; j<m ; j++){
                    ans.mat[i][j] = 0;
                    for(int k=0 ; k<m ; k++){
                        ans.mat[i][j] += mat[i][k]*p.mat[k][j];
                        ans.mat[i][j] %= MOD;
                    }
                }
            }
            return ans;
        }
        void print()
        {
            for(int i=0 ; i<m ; i++){
                for(int j=0 ; j<m ; j++)
                    cout<<mat[i][j]<<" ";
                cout<<endl;
            }
        }
    };
    
    Matrix qpow(ll cnt , Matrix p)
    {
        Matrix ans;
        for(int i=0 ; i<m ; i++)
            for(int j=0 ; j<m ; j++)
                if(i == j) ans.mat[i][j] = 1;
                else ans.mat[i][j] = 0;
        while(cnt){
            if(cnt&1) ans = ans*p;
            p = p*p;
            cnt/=2;
    
        }
        return ans;
    }
    
    int char_to_int(char c)
    {
        if(c>='a'&&c<='z') return c-'a';
        else return 26+(int)(c-'A');
    }
    int main()
    {
      //  freopen("a.in" , "r" , stdin);
        while(scanf("%I64d%d%d" , &n , &m , &k) == 3)
        {
            Matrix p ;
            for(int i=0 ; i<m ; i++)
                for(int j=0 ; j<m ; j++) p.mat[i][j] = 1;
            for(int i=0;i<m;i++) dp[i]=1;
            for(int i=0 ; i<k ; i++)
            {
                scanf("%s" , s);
                int g = char_to_int(s[0]);
                int h = char_to_int(s[1]);
                p.mat[g][h] = 0;
            }
            Matrix final = qpow(n-1 , p);
    
            ll ans = 0;
            for(int i=0 ; i<m ; i++)
                for(int j=0 ; j<m ; j++){
                    ans += dp[i]*final.mat[j][i];
                    ans %= MOD;
                }
            printf("%I64d
    " , ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    第一册:lesson forty five。
    第一册:lesson forty three。
    马化腾2015港大演讲。
    Swing实现文件选择(目录选择)附导出
    SVN强制注释
    Websphere内存溢出的日志
    sql server2008 搭建链接服务器成功后查询时报Cannot obtain the schema rowset "DBSCHEMA_TABLES_INFO" for OLE DB provider "SQLNCLI10" for linked server "XXXXX". 的解决方法
    UML图例
    jSP的3种方式实现radio ,checkBox,select的默认选择值。
    通过js子页面回写父页面,改变父页面控件的值
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4253448.html
Copyright © 2011-2022 走看看