• 哈尔滨理工大学软件与微电子学院第八届程序设计竞赛同步赛(高年级) Solution


    A:

    Solved.

    分别处理出每个%7后余数的数字个数,再组合一下

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3  
     4 #define ll long long
     5 int n, m;
     6 ll cnt[2][10];
     7  
     8 ll calc(ll x, ll y)
     9 {
    10     if (x % 7 >= y) return x / 7 + 1; 
    11     return x / 7;
    12 }
    13 
    14 int main()
    15 {
    16     while (scanf("%d%d", &n, &m) != EOF)
    17     {
    18         memset(cnt, 0, sizeof cnt);
    19         for (int i = 0; i < 7; ++i)
    20         {
    21             cnt[0][i] += calc(n, i);
    22             cnt[1][i] += calc(m, i);
    23         }
    24         ll res = 0; 
    25         --cnt[0][0], --cnt[1][0];
    26         cnt[1][7] = cnt[1][0];
    27         for (int i = 0; i < 7; ++i)
    28             res += cnt[0][i] * cnt[1][7 - i];
    29         printf("%lld
    ", res);
    30     }
    31     return 0;
    32 }
    View Code

    B:

    Solved.

    状压DP.

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3  
     4 #define ll long long
     5 int n,m;
     6 ll f[12][1<<11];
     7 bool ins[1<<11];
     8 int main(){
     9         while(cin>>n>>m&&n){
    10                 for(int i=0;i<(1<<m);i++){
    11                         bool cnt=0,hasodd=0;
    12                         for(int j=0;j<m;j++)
    13                                 if((i>>j)&1)hasodd|=cnt,cnt=0;
    14                                 else  cnt^=1;
    15                         ins[i]=hasodd|cnt?0:1;
    16  
    17                 }
    18                 f[0][0]=1;
    19                 for(int i=1;i<=n;i++)
    20                         for(int j=0;j<(1<<m);j++){
    21                                 f[i][j]=0;
    22                                 for(int k=0;k<(1<<m);k++){
    23                                         if((j&k)==0&&ins[j|k])
    24                                                 f[i][j]+=f[i-1][k];
    25                                 }
    26                                  
    27                         }
    28                 cout<<f[n][0]<<endl;
    29         }
    30 }
    View Code

    C:

    Solved.

     1 #include<bits/stdc++.h>
     2  
     3 using namespace std;
     4  
     5 int n, s;
     6  
     7 int main()
     8 {
     9     while(~scanf("%d %d", &n, &s))
    10     {
    11         int Min = 0x3f3f3f3f;
    12         for(int i = 0; i < n; ++i)
    13         {
    14             int num = 0;
    15             scanf("%d" , &num);
    16             Min = min(Min, num);
    17         }
    18         printf("%d
    ", s * Min);
    19     }
    20     return 0;
    21 }
    View Code

    D:

    Solved.

     1 #include<bits/stdc++.h>
     2  
     3 using namespace std;
     4  
     5 const int maxn = 1010;
     6 int n, s;
     7 int arr[maxn];
     8  
     9 int main()
    10 {
    11     while(~scanf("%d %d", &n, &s))
    12     {
    13         for(int i = 1; i <= n; ++i)
    14         {
    15             scanf("%d", arr + i);
    16         }
    17         sort(arr + 1, arr + 1 + n);
    18         printf("%d
    ", arr[n - 2] * s);
    19     }
    20     return 0;
    21 }
    View Code

    E:

    Solved.

    最长公共子序列。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1010;
     4 int f[maxn][maxn];
     5 char s1[maxn],s2[maxn];
     6 int main(){
     7     cin>>s1+1>>s2+1;
     8     int n=strlen(s1+1),m=strlen(s2+1);
     9     for(int i=1;i<=n;i++)
    10     {
    11          
    12             for(int j=1;j<=m;j++)
    13             {
    14                     f[i][j]=max(f[i - 1][j], f[i][j - 1]);
    15                     if(s1[i]==s2[j])
    16                     {
    17                         f[i][j]=max(f[i][j],f[i-1][j-1] + 1);
    18                     }
    19  
    20             }
    21     }
    22     printf("%d
    ",f[n][m]);
    23 }
    View Code

    F:

    Solved.

    $dp[i][j][k] 表示到达i, j 的时候步数为k的方案数$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn=210;
     5 const ll MOD = 1e9 + 7;
     6 ll dp[maxn][maxn][maxn];
     7 int fx[8][2]={{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{2,-1},{-2,1},{-2,-1}};
     8 int n,m,s;
     9 inline bool  check(int x,int y){
    10         if(x<1 || x>n || y<1 ||y>m)return false;
    11         return true;
    12 }
    13 int main(){
    14     while(cin>>n>>m>>s)
    15     {
    16             memset(dp, 0, sizeof dp);
    17         dp[1][1][0]=1;
    18         for(int k=1;k<=s;k++)
    19         {
    20             for(int i=1;i<=n;i++)
    21             {
    22                 for(int j=1;j<=m;j++){
    23                     for(int t=0;t<8;t++)
    24                     {
    25                         int x=i+fx[t][0];
    26                         int y=j+fx[t][1];
    27                         if(check(x,y)){
    28                             dp[i][j][k]+=dp[x][y][k-1];
    29                             dp[i][j][k]%=MOD;
    30                         }
    31                     }
    32                 }
    33             }
    34         }
    35         cout<<dp[n][m][s]<<endl;
    36     }
    37 }
    View Code

    G:

    Unsolved.

    H:

    Solved.

    考虑离线,对$每个数处理出到L左边离它最近的非互质的数,以及到R右边$离它最近的非互质的数,

    再考虑先固定$l, 对每一个r处理出答案$

    再考虑什么时候把数的贡献加进去,仅当这个数的$L < l 的时候便可以加入贡献,贡献的范围是[pos, R - 1], pos 表示那个数的位置$

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3  
      4 #define N 100010
      5 #define pii pair <int, int>
      6 int n, q, a[N], l[N], r[N], dp[N], ans[N], vis[N];
      7 vector <int> fac[N];
      8 vector <pii> v[N], qv[N];
      9  
     10 namespace SEG
     11 {
     12     int a[N << 2], lazy[N << 2];
     13     void build(int id, int l, int r)
     14     {
     15         a[id] = 0;
     16         if (l == r) return;
     17         int mid = (l + r) >> 1;
     18         build(id << 1, l, mid);
     19         build(id << 1 | 1, mid + 1, r);
     20     }
     21     void pushdown(int id, int l, int r, int mid)
     22     {
     23         if (!lazy[id]) return;
     24         lazy[id << 1] += lazy[id];
     25         a[id << 1] += lazy[id] * (mid - l + 1);
     26         lazy[id << 1 | 1] += lazy[id];
     27         a[id << 1 | 1] += lazy[id] * (r - mid);
     28         lazy[id] = 0;
     29     }
     30     void pushup(int id) { a[id] = a[id << 1] + a[id << 1 | 1]; }
     31     void update(int id, int l, int r, int ql, int qr, int val)
     32     {
     33         if (l >= ql && r <= qr)
     34         {
     35             a[id] += val * (r - l + 1);
     36             lazy[id] += val;
     37             return;
     38         }
     39         int mid = (l + r) >> 1;
     40         pushdown(id, l, r, mid);
     41         if (ql <= mid) update(id << 1, l, mid, ql, qr, val);
     42         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr, val);
     43         pushup(id);
     44     }
     45     int query(int id, int l, int r, int pos)
     46     {
     47         if (l == r) return a[id];
     48         int mid = (l + r) >> 1;
     49         pushdown(id, l, r, mid);
     50         if (pos <= mid) return query(id << 1, l, mid, pos);
     51         else return query(id << 1 | 1, mid + 1, r, pos);
     52     }
     53 }
     54  
     55 void init()
     56 {
     57     for (int i = 2; i <= 100000; ++i)
     58     {
     59         if (vis[i]) continue;
     60         fac[i].push_back(i);
     61         for (int j = 2 * i; j <= 100000; j += i)
     62         {
     63             vis[j] = 1;
     64             fac[j].push_back(i);
     65         }
     66     }
     67 }
     68  
     69 int main()
     70 {
     71     init();
     72     while (scanf("%d%d", &n, &q) != EOF)
     73     {
     74         for (int i = 0; i <= n + 1; ++i) l[i] = 0, r[i] = n + 1, v[i].clear(), qv[i].clear();
     75         for (int i = 1; i <= n; ++i) scanf("%d", a + i);
     76         memset(vis, 0, sizeof vis);
     77         for (int i = 1; i <= n; ++i)
     78             for (auto it : fac[a[i]])
     79                 l[i] = max(l[i], vis[it]), vis[it] = i;
     80         memset(vis, 0x3f, sizeof vis);
     81         for (int i = n; i >= 1; --i)
     82             for (auto it : fac[a[i]])
     83                 r[i] = min(r[i], vis[it]), vis[it] = i;
     84         //for (int i = 1; i <= n; ++i) printf("%d %d
    ", l[i], r[i]);
     85         //for (int i = 1; i <= n; ++i) for (int j = 0, len = fac[a[i]].size(); j < len; ++j) printf("%d%c", fac[a[i]][j], " 
    "[j == len - 1]);
     86         for (int i = 1; i <= n; ++i)
     87             v[l[i]].emplace_back(r[i], i);
     88         for (int qq = 1, l, r; qq <= q; ++qq)
     89         {
     90             scanf("%d%d", &l, &r);
     91             qv[l].emplace_back(r, qq);
     92         }
     93         SEG::build(1, 1, n);
     94         for (int i = 1; i <= n; ++i)
     95         {
     96             for (auto it : v[i - 1])
     97                 SEG::update(1, 1, n, it.second, it.first - 1, 1);
     98             for (auto it : qv[i])
     99                 ans[it.second] = SEG::query(1, 1, n, it.first);
    100             SEG::update(1, 1, n, i, r[i] - 1, -1);
    101         }
    102         for (int i = 1; i <= q; ++i) printf("%d
    ", ans[i]);
    103     }
    104     return 0;
    105 }
    View Code

    I:

    Solved.

    特判$n == 0 并且 m == 0 的情况$

    其他情况下,因为$k >= |n - m| 先手的人只需要去掉石子使得两堆相同,然后跟着另一个人取就可以必胜$

     1 #include<bits/stdc++.h>
     2  
     3 using namespace std;
     4  
     5 typedef long long ll;
     6  
     7 ll n, m, k;
     8  
     9 int main()
    10 {
    11     while(~scanf("%lld %lld %lld", &n, &m, &k))
    12     {
    13         if(n == 0 || m == 0) puts("LAOZI CHUI SI NI!");
    14         else puts("HAI YOU SEI!");
    15     }
    16     return 0;
    17 }
    View Code

    J:

    Solved.

    考虑 末尾两位为00, 25, 50, 75四种状态

      1 #include<bits/stdc++.h>
      2  
      3 using namespace std;
      4  
      5 const int INF = 0x3f3f3f3f;
      6 const int maxn = 1e5 + 10;
      7  
      8 char str[maxn];
      9  
     10 int main()
     11 {
     12     while(~scanf("%s", str + 1))
     13     {
     14         int ans = INF;
     15         int len = strlen(str + 1);
     16  
     17         //00
     18         int tmp1 = -1, tmp2 = -1;
     19         for(int i = len; i >= 1; --i)
     20         {
     21             if(str[i] == '0')
     22             {
     23                 if(tmp1 == -1) tmp1 = len - i;
     24                 else if(tmp2 == -1)
     25                 {
     26                     tmp2 = len - i - 1;
     27                     break;
     28                 }
     29             }
     30         }
     31         if(tmp1 != -1 && tmp2 != -1) ans = min(ans, tmp1 + tmp2);
     32  
     33         //25
     34         tmp1 = -1, tmp2 = -1;
     35         for(int i = len; i >= 1; --i)
     36         {
     37             if(str[i] == '5')
     38             {
     39                 if(tmp1 == -1) tmp1 = len - i;
     40             }
     41             if(str[i] == '2')
     42             {
     43                 if(tmp2 == -1) tmp2 = len - i;
     44             }
     45         }
     46  
     47         if(tmp1 != -1 && tmp2 != -1)
     48         {
     49             if(tmp1 < tmp2)
     50             {
     51                 ans = min(ans, tmp1 + tmp2 - 1);
     52             }
     53             else
     54             {
     55                 ans = min(ans, tmp1 + tmp2);
     56             }
     57         }
     58  
     59         //50
     60         tmp1 = -1, tmp2 = -1;
     61         for(int i = len; i >= 1; --i)
     62         {
     63             if(str[i] == '0')
     64             {
     65                 if(tmp1 == -1) tmp1 = len - i;
     66             }
     67             if(str[i] == '5')
     68             {
     69                 if(tmp2 == -1) tmp2 = len - i;
     70             }
     71         }
     72          
     73         if(tmp1 != -1 && tmp2 != -1)
     74         {
     75             if(tmp1 < tmp2)
     76             {
     77                 ans = min(ans, tmp1 + tmp2 - 1);
     78             }
     79             else
     80             {
     81                 ans = min(ans, tmp1 + tmp2);
     82             }
     83         }
     84         //75
     85         tmp1 = -1, tmp2 = -1;
     86         for(int i = len; i >= 1; --i)
     87         {
     88             if(str[i] == '5')
     89             {
     90                 if(tmp1 == -1) tmp1 = len - i;
     91             }
     92             if(str[i] == '7')
     93             {
     94                 if(tmp2 == -1) tmp2 = len - i;
     95             }
     96         }
     97         if(tmp1 != -1 && tmp2 != -1)
     98         {
     99             if(tmp1 < tmp2)
    100             {
    101                 ans = min(ans, tmp1 + tmp2 - 1);
    102             }
    103             else
    104             {
    105                 ans = min(ans, tmp1 + tmp2);
    106             }
    107         }
    108         if(ans == INF) ans = -1;
    109         printf("%d
    ", ans);       
    110     }
    111     return 0;
    112 }
    View Code
  • 相关阅读:
    ArrayList集合封装 类 并通过方法调用
    ArrayList集合的基本操作
    方法的重复定义和重载
    方法间值的传递,二维数组的定义和遍历
    赋值运算,逻辑运算符,引用数据类型
    Javase;jdk的安装调试;基础语法和变量以及基础数据类型
    E-R画图规则和数据库设计的三大范式
    sql多表查询和子查询
    sql约束的使用
    sql表操作的基础语法
  • 原文地址:https://www.cnblogs.com/Dup4/p/10050587.html
Copyright © 2020-2023  润新知