Codeforces Round 1012 (Div. 2)

Codeforces Round 1012 (Div. 2)

A

直接看一看s%(x+y)的余数即可,简单的数学推导

#include
using namespace std;
 
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int x,y,a;
        cin>>x>>y>>a;
        int k=a%(x+y);
        if(x>k) cout<<"NO"< 
  

B

一开始的想法是类似于一个dp看看这个1的左侧和上侧有没有1,如果有是对的不然直接退出

但是可能会跳出,test3就wa了

重新思考一下,发现充要条件是它的上方或左侧全部都是1

#include
using namespace std;
const int N=55;
char g[N][N];
 
void slove()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>g[i][j];
        }
    }
 
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(g[i][j]=='1')
            {
                bool st1=1,st2=1;
                for(int k=1;k<=i;k++)
                {
                    if(g[k][j]=='0')
                    {
                        st1=0;
                        break;
                    }
                }
                for(int k=1;k<=j;k++)
                {
                    if(g[i][k]=='0')
                    {
                        st2=0;
                        break;
                    }
                }
                if(st1==0&&st2==0)
                {
                    cout<<"NO"<>t;
    while(t--) slove();
    return 0;
}

C

就是动态维护一下起点到哪些桌子点最小的点,和到座位最小的点,可以用小根堆维护

也可以用数组加一个判重数组维护,本人不太会写重载函数所以使用数组

到这里其实就不会写了,剩下的都是看题解补的题

#include
using namespace std;
vector> b;
 
void init()
{
    int m=320;
    for(int i=0;i>n;
    vector a(n);
    for(int i=0;i>a[i];
    int m=sqrt(2*n)+3;
    vector> f(m*3,vector(m*3,0));
    vector> g(m,vector(m,0));
    int k1=0,k0=0;
    for(int i=0;i>q;
    while(q--) slove();
    return 0;
}

D

构造题,我们想取一个质数让 i=1时它是质数,但是当i=2时它肯定不是质数了,那么i=3时

希望它是就选取2为1和3的等差中项即可

由于勃兰特---切比雪夫定理和题意我们只需要在n/3何2n/3之间找一个质数即可

#include
using namespace std;
const int N=100010;
int prime[N],cnt;
bool st[N];
 
void init()
{
    for(int i=2;i<=N;i++)
    {
        if(st[i]==0) prime[cnt++]=i;
        for(int j=0;prime[j]<=N/i;j++)
        {
            st[prime[j]*i]=true;
            if(i%prime[j]==0) break;
        }
    }
}
 
void slove()
{
    int n;
    cin>>n;
    int l=max(1,n/3);
    int r=(2*n)/3;
    int p=2;
    for(int i=0;i<=cnt;i++)
    {
        if(prime[i]>=l&&prime[i]<=r)
        {
            p=prime[i];
            break;
        }
    }
    
    vector ans;
    ans.push_back(p);
    
    for(int i=1;;i++)
    {
        if(p-i>=1&&p+i<=n)
        {
            ans.push_back(p-i);
            ans.push_back(p+i);
        }
        else if(p-i>=1) ans.push_back(p-i);
        else if(p+i<=n) ans.push_back(p+i);
        else break;
    }
    
    for(int t : ans) cout<>t;
    while(t--) slove();
    return 0;
}

E1

其实想法和答案以经很接近了,就是找每一个数变为0的步数然后求一个最大值,但是没往深想

其实题干中已经有提示了,题一定有解,sum(b)>=sum(a);说明一个数变为0的步数一定和sum(b)

和sum(a)有关,我们发现经过第一次操作后大数变为其和小数的差,小数直接变为0,然后a错位减

经过一些推导发现什么时候sum(b)>sum(a)时其就为0了

using namespace std;
typedef long long LL;
int n;
 
LL c_sum(LL p[],int l,int r)
{
    if(l>r)return p[n-1]-p[l-1]+p[r];
    else
    {
        if(l-1>=0) return p[r]-p[l-1];
        else return p[r];
    }
}
 
void slove()
{
    int k;
    scanf("%d%d",&n,&k);
    vector a(n);
    vector b(n);
    LL p[n];
    for(int i=0;i c(n,1);
    
    for(int i=n-1;i>=0;i--)
    {
        int len=1;
        while(c_sum(p,i,(i+len-1)%n)>0)
        {
            len+=c[(i+len)%n];
        }
        c[i]=len;
    }
    
    int res=-1;
    for(int i=0;i 
 

你可能感兴趣的:(算法,c++,图论)