zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 84 (Rated for Div. 2) A-E题解

    A. Sum of Odd Integers

    首先可以算出从1开始到第k个奇数之和。如果和大于n,则不可能存在k个奇数加和等于n,否则用n减去前k个奇数的和,这个差值若是偶数,直接加到最大的奇数上,就可以满足题意要求,否则输出no。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 int main(){
     5     int t;
     6     cin>>t;
     7     while(t--){
     8         ll n,k;
     9         cin>>n>>k;
    10         ll d = (1+2*k-1)*k/2;
    11         ll t = n - d;
    12         if(t>=0 && t%2 == 0) cout<<"YES"<<endl;
    13         else cout<<"NO"<<endl;
    14     }
    15     return 0;
    16 }
    View Code

    B. Princesses and Princes

    贪心的去匹配每个Princesses当前可以匹配的最中意的Princes,如果存在没有匹配上的Princesses,随便和一个没有匹配过的Princes匹配即可。纯阅读理解题。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 int main(){
     5     int t;
     6     cin>>t;
     7     while(t--){
     8         int n;cin>>n;
     9         vector<int> v[n];
    10         int pr[n+1];
    11         int dr[n+1];
    12         memset(dr,0,sizeof(dr));
    13         memset(pr,0,sizeof(pr));
    14         for(int i = 1;i<=n;i++){
    15             int k;scanf("%d",&k);
    16             for(int j = 0;j<k;j++){
    17                 int t;scanf("%d",&t);
    18                 if(dr[i] == 0 && pr[t] == 0) pr[t] = 1,dr[i] = 1;
    19             }
    20         }
    21         vector<int> r1,r2;
    22         int f = 0;
    23         for(int i = 1;i<=n;i++){
    24             if(dr[i] == 0) {
    25                 f = 1;r1.push_back(i);
    26             }
    27             if(pr[i] == 0) {
    28                 f = 1;r2.push_back(i);
    29             }
    30         }
    31         if(f == 0){
    32             cout<<"OPTIMAL"<<endl;
    33         }
    34         else{
    35             cout<<"IMPROVE"<<endl;
    36             for(int i = 0;i<r1.size();i++){
    37                 cout<<r1[i]<<" "<<r2[i]<<endl; 
    38                 break;
    39             }
    40         }
    41     }
    42     return 0;
    43 }
    View Code

    C. Game with Chips

    构造题。按最坏的情况考虑,直接先把所有的chips移动到一个角落里,然后从这个角落S形遍历一遍棋盘即可,这样必定可以经过棋盘上所有的关键点,整个操作必定不会超过2*m*n次,故不可能存在-1的情况。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 int main()
     5 {
     6  
     7     int n,m,k;
     8     cin>>n>>m>>k;
     9     for(int i=1;i<=k;i++)
    10     {
    11         int x,y;scanf("%d%d",&x,&y);
    12     }
    13     for(int i=1;i<=k;i++)
    14     {
    15        int x,y;scanf("%d%d",&x,&y);
    16     }
    17     int tn=0;
    18         tn =tn+n-1+m-1+(n-1)*m+m-1;
    19     cout << tn << endl;
    20     for(int i=1; i<m; i++ )
    21         cout<<"L";
    22     for(int i=1; i<n; i++)
    23         cout<<"U";
    24             for(int i=1; i<n; i++)
    25                 {
    26                     for(int j=1; j<m; j++)
    27                     if(i&1)
    28                         cout<<"R";
    29                     else
    30                         cout<<"L";
    31                             printf("D");
    32                 }
    33     for(int j=1; j<m; j++)
    34         if (n&1)
    35             printf("R");
    36         else
    37             printf("L");
    38 
    39     return 0;
    40 }
    View Code

    D. Infinite Path

    一道定义在环上的排列幂定义题。p * p = p[ p [ i ] ] ,按照题目所给的定理可以轻易推导出从任意一p[i]出发,做排列幂运算之后最终回到p[i],把i和p[i]连边,这样可以构成一个环,而整个序列可以构成多个不相交环。对于一个环,从任意一点出发,走k步,也就是pk[i] ,会有c[i] = c[pk[i] ] ,也可能会有c[p2k[i] ]......,也就是说每次走从一点开始,相隔k个点,他们的c[i]是相等的,怎么求最小的k?当是从环长度的因子开始枚举,只有是因子k才能从某一起点开始,每次走k步,绕一圈回到这个起点。

    预处理所有的环,然后枚举环,在环中枚举环长度的因子,再去检查环上是否存在合法的k,每次取k的最小值。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn = 2e5 +5;
     5 int k,n,cnt,ans;
     6 int p[maxn],c[maxn],vis[maxn],g[maxn];
     7 bool ok(int x,int y){
     8     for(int i = 1;i<=x;i++){//在长度为x的范围内枚举起点
     9         int f = 0,t = i;
    10         for(int j = 1;j<=y;j++){//整个环上有y个相隔x的点
    11             if(c[g[t]] != c[g[i]]){//检查每次移动k步到的点,其c值是否相等。
    12                 f = 1;break;
    13             }
    14             t = (t + x - 1) %cnt + 1;//t是下一个点的位置
    15         }
    16         if(!f) return 1;
    17     }
    18     return 0;
    19 }
    20 void dfs(int x){
    21     cnt = 1;
    22     g[cnt] = x,vis[x] = 1;
    23     for(int i = p[x];i!=x;i=p[i]) vis[i] = 1,g[++cnt] = i;//从一点开始预处理环,结点存入g数组
    24     for(int i = 1;i<=sqrt(cnt);i++){//枚举环长度cnt的因子
    25         if(cnt%i == 0){
    26             if(ok(i,cnt/i)) {ans = min(ans,i);return;} //检查k = i是否合法
    27             if(ok(cnt/i,i) )ans = min(ans,cnt/i);//检查k = cnt/i是否合法
    28         }
    29     }
    30 }
    31 int main()
    32 {
    33     int t;
    34     scanf("%d",&t);
    35     while(t--){
    36        scanf("%d",&n);
    37        for(int i = 1;i<=n;i++) scanf("%d",&p[i]);
    38        for(int i = 1;i<=n;i++) scanf("%d",&c[i]);
    39        ans = 2e5+10;
    40        for(int i = 1;i<=n;i++) vis[i] = 0; 
    41        for(int i = 1;i<=n;i++) {
    42               if(!vis[i]) dfs(i);
    43        }
    44        cout<<ans<<endl;
    45     }
    46     return 0;
    47 }
    View Code

    E. Count The Blocks

    计数题。n位数,首先考虑block的长度为1,各个位置都可以放置0~10这样不同的数字,一共10个数字,对于其中1个位置,这个位置可以放10种可能的数字,其左右相邻的位放置9种可能的数,不相邻的其他位可以任意放置10个数字。

    考虑长度n的数,block长度为k

    1.左右两个端点对答案的贡献是2*10*9*10n-k-1 ,2是2个端点,10是端点可以放置10种可能的数,9是其相邻位置只能放9种可能,10n-k-1是其他点可以放置的数字有多少种。

    2.中间的长度为k的段,10*9*9*10n-k-2,10是这一段放置10种可能的数字,2个9是这一段左右端点相邻的点要和段内数字不同,有9种可能,10n-k-2 是其他点可以放置的数字有多少种可能,这样的段一共有n-k-1个,再乘一下即可。

    首先要预处理一下10的n次方。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const ll mod = 998244353;
     5 const int maxn = 2e5+5;
     6 ll n;
     7 ll f[maxn];
     8 void pre(){
     9     f[1] = 10;
    10     for(int i = 2;i<=n;i++){
    11        f[i] = f[i-1]*10%mod;        
    12     }
    13 }
    14 int main()
    15 {
    16     cin>>n;
    17     pre();
    18     for(int i = 1;i<n;i++){
    19         ll d = n + 1 - i;
    20         ll x = ((ll(2*9)*f[n-i])%mod + (ll(d-2)*9*9*f[n-i-1])%mod)%mod;
    21         cout<<x<<" ";
    22     }
    23     cout<<10;
    24     return 0;
    25 }
    View Code
  • 相关阅读:
    java 在线网络考试系统源码 springboot mybaits vue.js 前后分离跨域
    springboot 整合flowable 项目源码 mybiats vue.js 前后分离 跨域
    flowable Springboot vue.js 前后分离 跨域 有代码生成器 工作流
    Flowable 工作流 Springboot vue.js 前后分离 跨域 有代码生成器
    java 企业 网站源码 后台 springmvc SSM 前台 静态化 代码生成器
    java 进销存 商户管理 系统 管理 库存管理 销售报表springmvc SSM项目
    基于FPGA的电子计算器设计(中)
    基于FPGA的电子计算器设计(上)
    FPGA零基础学习:SPI 协议驱动设计
    Signal tap 逻辑分析仪使用教程
  • 原文地址:https://www.cnblogs.com/AaronChang/p/12571826.html
Copyright © 2011-2022 走看看