Codeforces Round #674 (Div. 3)

原题链接

题外话

恢复性训练

A

题意

(就是告诉你一个公寓楼层分布, 第一层是 1 和 2 , 第二层是 3 到x+2 ,第三层 是x+2 +1 到 2*x+2,以此类推,然后问你一个房间他在几楼)

思路

直接通过题意暴力敲就行

代码

#include <cstdio>
#include <algorithm>
#include<iomanip>
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <cstring>
#include<stack>
#include <cassert>
#include<map>
#define cl(x) memset(x,0,sizeof(x))
#define rep(i,a,b) for(i=a;i<=b;i++)
#define drep(i,a,b) for(i=a;i>=b;i--)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define pb push_back
#define de(x) cerr<<#x<<" = "<<x<<endl
#define __i __int128
#define dbg(x...) do { cout << "33[32;1m" << #x << " -> "; err(x); } while (0)

using namespace std;
//using namespace __gnu_pbds;
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pLL;
const LL Max = 9.1e10;
const int N =5.1e5;
const int maxn = 200010;

LL   n, k, m ;
LL ar[N],br[N];
LL i,j,g;
LL MOD = 998244353 ;

void answer (){
    cin >> n>> m ;
    if(n==1 ||n ==2){
        cout<<1<<endl;
        return;
    }
    if((n-2)%m!=0)cout<<(n-2)/m +2<<endl;
    else cout<<(n-2)/m +1<<endl;
   return ;
 }


int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
//       pre();
    LL t;
//    sld(t);
cin >> t ;
    while(t--)
        answer();


    return 0;

}


B

题意

给你若干个22 的正方形,每个块里填写一个数字, 问你是否可以拼出一个nm的对称正方形

思路

通过看note 其实很清晰的知道只要(1,2) 和(2,1)这两个地方数字相同的小正方形存在, 就能拼出来, 所以判断是否有这个东西存在就行
别忘了如果m 不是偶数,一定不可以, (具体自己画图)

代码

#include <cstdio>
#include <algorithm>
#include<iomanip>
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <cstring>
#include<stack>
#include <cassert>
#include<map>
#define cl(x) memset(x,0,sizeof(x))
#define rep(i,a,b) for(i=a;i<=b;i++)
#define drep(i,a,b) for(i=a;i>=b;i--)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define pb push_back
#define de(x) cerr<<#x<<" = "<<x<<endl
#define __i __int128
#define dbg(x...) do { cout << "33[32;1m" << #x << " -> "; err(x); } while (0)

using namespace std;
//using namespace __gnu_pbds;
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pLL;
const LL Max = 9.1e10;
const int N =5.1e5;
const int maxn = 200010;
LL   n, k, m ;
LL ar[N],br[N];
LL i,j,g;
void answer (){
  cin >> n >> m;
  int flag =0 ;
  for(int i=1 ;i<=n;i++ ){
    int x1, x2 , y1 ,y2;
    cin >>x1 >> y1 >> x2 >> y2 ;
    if(y1 == x2 ){
        flag =1 ;
    }
  }
    if(flag && m%2!=1 )cout <<"YeS"<<endl;
    else cout<<"NO"<<endl;
   return ;
 }


int main()
{
//    ios::sync_with_stdio(0);
//    cin.tie(0), cout.tie(0);
//       pre();
    LL t;
//    sld(t);
cin >> t ;
    while(t--)
        answer();


    return 0;

}

C

题意

一开始数组里面有一个1 ,然后你有两种操作选项

  1. 在数组中找一个数 + 1
  2. 在数组中找一个数 复制一个进数组
    然后问你至少能到达给定的点的最小操作次数

思路

要是找最小的操作次数肯定要使用最多的复制操作, 所以由此想到开根(用开根后的数进行复制是最少的),然后判断一下开根后的数和给定的数之间是否可以取模,能的话 就 - 1 ,不能的话就不用

代码

#include <cstdio>
#include <algorithm>
#include<iomanip>
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <cstring>
#include<stack>
#include <cassert>
#include<map>
#define cl(x) memset(x,0,sizeof(x))
#define rep(i,a,b) for(i=a;i<=b;i++)
#define drep(i,a,b) for(i=a;i>=b;i--)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define pb push_back
#define de(x) cerr<<#x<<" = "<<x<<endl
#define __i __int128
#define dbg(x...) do { cout << "33[32;1m" << #x << " -> "; err(x); } while (0)

using namespace std;
//using namespace __gnu_pbds;
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pLL;
const LL Max = 9.1e10;
const int N =5.1e5;
const int maxn = 200010;

void clear(unsigned char *pta, int size )
{//结构体初始化
    while(size>0)
    {
        *pta++ = 0;
        size --;
    }
}

LL   n, k, m ;
LL ar[N],br[N];
LL i,j,g;
LL MOD = 998244353 ;

//f是该长度最小的坐标 ans 是最后输出的数 , last 是相同的数上一个位置

LL fac[N],inv_fac[N];
//快速幂
LL qpow(LL x, LL y ){
    x%=MOD;
    long long res=1%MOD;
    while(y){
        if(y&1)res=res*x%MOD;
        y>>=1;
        x=x*x%MOD;
    }
    return res;

}

void pre(){
    fac[0] =1 ;
    for(int i=1;i<N;i++){
        fac[i] =fac[i-1] * i %MOD;
    }
    inv_fac[N - 1 ] = qpow(fac[N - 1] , MOD-2 ) ;

    for(int i =N-2 ;i>=0 ;i--){
        inv_fac[i] = inv_fac[i+1] * (i+1) %MOD;
    }

}

LL C (LL a ,LL b){
    if(a<0 || b> a )//因为是C(a,b) 所以b《= a
    {
        return 0;
    }

    return fac[a] * inv_fac[b] % MOD *inv_fac[a-b]%MOD;//a 的阶乘 / ( b的阶乘 * (a-b的阶乘))

}

void answer (){
  cin >> n ;
  if(n==1 ){
    cout<<0<<endl;
    return ;
  }
//  cout <<n<<endl;
    m = (LL)sqrt(n);
//    cout <<m<<endl;
    LL cnt = m-1 ;
    if(n%m!=0)cnt += n/m ;
    else cnt +=n/m -1;
    cout<<cnt <<endl;


   return ;
 }


int main()
{
//    ios::sync_with_stdio(0);
//    cin.tie(0), cout.tie(0);
//       pre();
    LL t;
//    sld(t);
cin >> t ;
    while(t--)
        answer();


    return 0;

}

D

题意

这个就是问你用最少的数添加到数组中,使这个数组的所有子序列之和都不能为零

思路

只想到了前缀和,没想到离散化
先用前缀和加一遍整个数组的数,然后每次判断从前面到目标数组下标之间是否有相同的数,有的话就代表这里面出现零,需要加一个数。
注意一下0这个数, 默认要有一个

代码

#include <cstdio>
#include <algorithm>
#include<iomanip>
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <cstring>
#include<stack>
#include <cassert>
#include<map>
#define cl(x) memset(x,0,sizeof(x))
#define rep(i,a,b) for(i=a;i<=b;i++)
#define drep(i,a,b) for(i=a;i>=b;i--)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define pb push_back
#define de(x) cerr<<#x<<" = "<<x<<endl
#define __i __int128
#define dbg(x...) do { cout << "33[32;1m" << #x << " -> "; err(x); } while (0)

using namespace std;
//using namespace __gnu_pbds;
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pLL;
const LL Max = 9.1e10;
const int N =5.1e5;
const int maxn = 200010;

void clear(unsigned char *pta, int size )
{//结构体初始化
    while(size>0)
    {
        *pta++ = 0;
        size --;
    }
}

LL   n, k, m ;
LL ar[N],br[N];
LL i,j,g;
LL MOD = 998244353 ;

//f是该长度最小的坐标 ans 是最后输出的数 , last 是相同的数上一个位置

LL fac[N],inv_fac[N];
//快速幂
LL qpow(LL x, LL y ){
    x%=MOD;
    long long res=1%MOD;
    while(y){
        if(y&1)res=res*x%MOD;
        y>>=1;
        x=x*x%MOD;
    }
    return res;

}

void pre(){
    fac[0] =1 ;
    for(int i=1;i<N;i++){
        fac[i] =fac[i-1] * i %MOD;
    }
    inv_fac[N - 1 ] = qpow(fac[N - 1] , MOD-2 ) ;

    for(int i =N-2 ;i>=0 ;i--){
        inv_fac[i] = inv_fac[i+1] * (i+1) %MOD;
    }

}

LL C (LL a ,LL b){
    if(a<0 || b> a )//因为是C(a,b) 所以b《= a
    {
        return 0;
    }

    return fac[a] * inv_fac[b] % MOD *inv_fac[a-b]%MOD;//a 的阶乘 / ( b的阶乘 * (a-b的阶乘))

}

void answer (){
  cin >> n;
  for(int i=1;i<=n;i++){
    cin >>ar[i];
  }
  map<LL , LL > mp;
  LL cnt =0 ;
  mp[0] =1 ;
  for(int i=1;i<=n;i++){
    m += ar[i];
    if(mp[m]){
        mp.clear();
        m = ar[i] ;
        cnt ++ ;
        mp[0] =1 ;
    }
    mp[m] =1 ;


  }
    cout<<cnt<<endl ;

   return ;
 }


int main()
{
//    ios::sync_with_stdio(0);
//    cin.tie(0), cout.tie(0);
//       pre();
    LL t;
////    sld(t);
//cin >> t ;
//    while(t--)
        answer();


    return 0;

}


E

题意

问你石头剪刀布, 第一个人最少和最多能赢多少把

思路

最多就是最好的情况
最少就是最坏的情况

代码


#include <cstdio>
#include <algorithm>
#include<iomanip>
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <cstring>
#include<stack>
#include <cassert>
#include<map>
#define cl(x) memset(x,0,sizeof(x))
#define rep(i,a,b) for(i=a;i<=b;i++)
#define drep(i,a,b) for(i=a;i>=b;i--)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define pb push_back
#define de(x) cerr<<#x<<" = "<<x<<endl
#define __i __int128
#define pn printf("
");
#define pk printf(" ");
#define p(n) printf("%d",n);
#define pln(n) printf("%d
",n);
#define s(n) scanf("%d",&n);
#define ss(n) scanf("%s",n);
#define ps(n) printf("%s",n);
#define sld(n) scanf("%lld",&n);
#define pld(n) printf("%lld",n);
#define slf(n) scanf("%lf",&n);
#define plf(n) printf("%lf",n);
#define sc(n) scanf("%c",&n);
#define pc(n) printf("%c",n);
#define dbg(x...) do { cout << "33[32;1m" << #x << " -> "; err(x); } while (0)

using namespace std;
//using namespace __gnu_pbds;
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pLL;
const LL Max = 9.1e10;
const int N =3.1e5;
const int maxn = 200010;

void clear(unsigned char *pta, int size )
{//结构体初始化
    while(size>0)
    {
        *pta++ = 0;
        size --;
    }
}

LL   n, k, m ;
LL ar[N],br[N];
LL i,j,g;
LL ch[110][4];
LL MOD = 998244353 ;


LL fac[N],inv_fac[N];

//快速幂
LL qpow(LL x, LL y ){
    x%=MOD;
    long long res=1%MOD;
    while(y){
        if(y&1)res=res*x%MOD;
        y>>=1;
        x=x*x%MOD;
    }
    return res;

}

void pre(){
    fac[0] =1 ;
    for(int i=1;i<N;i++){
        fac[i] =fac[i-1] * i %MOD;
    }
    inv_fac[N - 1 ] = qpow(fac[N - 1] , MOD-2 ) ;

    for(int i =N-2 ;i>=0 ;i--){
        inv_fac[i] = inv_fac[i+1] * (i+1) %MOD;
    }

}

LL C (LL a ,LL b){
    if(a<0 || b> a )//因为是C(a,b) 所以b《= a
    {
        return 0;
    }

    return fac[a] * inv_fac[b] % MOD *inv_fac[a-b]%MOD;//a 的阶乘 / ( b的阶乘 * (a-b的阶乘))

}
void answer(){
   LL x, y , z ;
   cin >> x >> y >>z ;
   LL x1 , y1 , z1;
   cin >>x1>>y1>> z1;
   cout<<min( x-x1-z1 <0?0:x-x1-z1 ,y1 ) + min(y - y1 - x1< 0 ? 0: y - y1 - x1,z1 ) + min(z -z1 - y1 < 0 ?0 : z -z1 - y1 , x1)<<" ";
   cout<<min(x,y1)+ min(y , z1) + min(z , x1)<<endl;

   return ;
 }


int main()
{
//    ios::sync_with_stdio(0);
//    cin.tie(0), cout.tie(0);
//       pre();
    LL t;s(t);
//    while(t--)
        answer();


    return 0;

}
原文地址:https://www.cnblogs.com/gaohaoy/p/13765203.html