2018多校联合训练4

http://acm.hdu.edu.cn/userloginex.php?cid=805

过了6题,第一次进入前100名

 

1012:直接从1走到n

solved by wyq

#include<stdio.h>
#include<math.h>
int a[100005];
int reabs(int x)
{
    if(x<0)return -x;
    else return x;
}
int main()
{
    int T,i,n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        printf("%d\n",(int)(sqrt(reabs(a[1]-a[n]))));
    }
    return 0;
}

 

1004:和出题人心有灵犀2333

solved by lyy

#include <bits/stdc++.h>
using namespace std;
#define ll long long
struct st
{
    int a,b;
}p[105];
int t,n,m;

bool cmp(st a,st b)
{
    return a.b<b.b;
}

int main()
{
    scanf("%d",&t);
    while (t--)
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++)
        {
            scanf("%d%d",&p[i].a,&p[i].b);
        }
        sort(p+1,p+n+1,cmp);
        int ans=0;
        for (int i=1;i<=n;i++)
        {
            if (m<p[i].b+1) break;
            else
            {
                ans++;
                m/=p[i].b+1;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

1011:

solved by wyq

#include<stdio.h>
#include<math.h>
#include<string.h>
char s[1005];
bool isnum(int x,int y)
{
    if(x>y)return false;
    //printf("%d %d\n",x,y);
    if(x!=y && s[x]=='0')return false;
    int i;
    for(i=x;i<=y;i++)
        if(s[i]=='+' || s[i]=='*')return false;
    for(i=x;i<=y;i++)
    {
        if(s[i]=='?')s[i]='1';
    }
    return true;
}
int main()
{
    int T,i,n;
    scanf("%d",&T);
    while(T--)
    {
       scanf("%s",s);
       int lens=strlen(s);
       if(s[0]=='0' && s[1]=='?')s[1]='+';
       for(i=2;i<=lens;i++)
            if((s[i-2]=='+' || s[i-2]=='*')&& s[i-1]=='0' && s[i]=='?')s[i]='+';
        int lastfuhao=lens;
        bool ans=true;
       for(i=lens-1;i>=0;i--)
       {
           if(s[i]=='+' || s[i]=='*')
           {
               ans=isnum(i+1,lastfuhao-1);
               lastfuhao=i;
               if(!ans)break;
           }
       }
       if(ans)ans=isnum(0,lastfuhao-1);
       if(!ans)printf("IMPOSSIBLE\n");
       else printf("%s\n",s);
    }
    return 0;
}

 

1002:搞不懂为什么是莫队算法,不过和莫队算法比较相似,按照\sqrt{n}分块,首先求出所有200的倍数行,然后利用T(n,k) = 2 T(n-1,k-1) + C_{n-1}^{k}

递推

solved by lyy

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1000000007;
ll f[100005];
ll ff[100005];
ll c[205][100005];
int t,n,m;

long long inv(long long a,long long m)
{
    if(a == 1)return 1;
    return inv(m%a,m)*(m-m/a)%m;
}

int main()
{
    f[0]=1;
    for (int i=1;i<=100000;i++)
    {
        f[i]=f[i-1]*i%mod;
    }
    for (int i=0;i<=100000;i++)
    {
        ff[i]=inv(f[i],mod);
    }
    c[0][0]=0;
    for (int i=1;i<=200;i++)
    {
        ll x=1;
        c[i][0]=1;
        for (int j=1;j<=500*i;j++)
        {
            x=(x+f[i*500]*ff[j]%mod*ff[500*i-j]%mod)%mod;
            c[i][j]=x;
        }
    }
    scanf("%d",&t);
    while (t--)
    {
        scanf("%d%d",&n,&m);
        if (m<=600)
        {
            ll x=1;
            for (int i=1;i<=m;i++)
            {
                x=(x+f[n]*ff[i]%mod*ff[n-i]%mod)%mod;
            }
            printf("%lld\n",x);
        }
        else if (n==m)
        {
            ll ans=1;
            for (int i=1;i<=n;i++)
            {
                ans=ans*2%mod;
            }
            printf("%lld\n",ans);
        }
        else
        {
            vector<ll> v;
            ll ans=0;
            while (n%500!=0)
            {
                v.push_back(f[n-1]*ff[m]%mod*ff[n-1-m]%mod);
                m--;
                n--;
            }
            reverse(v.begin(),v.end());
            ans=c[n/500][m];
            for (int i=0;i<v.size();i++)
            {
                ans=(ans*2+v[i])%mod;
            }
            printf("%lld\n",ans);
        }
    }
    return 0;
}

 

1005:行和列都是2L的周期,第i行第j 列的数是:

\frac{i*(i+3)+j*(j+1)+2ij}{2} \%L

那么很容易分析出i和j都是2L的周期,更确切的是当n位奇数时周期是L,n为偶数时周期为2L(一开始把周期当L,结果Wa了),

然后分成4块求即可

solved by lyy

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int t;
int l,q;
int a[22];
int p[22][22];
int r[22];
int row[22][22];
int col[22][22];
ll s[22];

int main()
{
    scanf("%d",&t);
    while (t--)
    {
        memset(p,0,sizeof(p));
        memset(r,0,sizeof(r));
        memset(s,0,sizeof(s));
        memset(row,0,sizeof(row));
        memset(col,0,sizeof(col));
        scanf("%d",&l);
        int k=l*2;
        for (int i=0;i<l;i++)
        {
            scanf("%d",&a[i]);
        }
        for (int i=0;i<k;i++)
        {
            for (int j=0;j<k;j++)
            {
                p[i][j]=(i*(i+3)/2+j*(j+1)/2+i*j)%l;
                r[p[i][j]]++;
                row[p[i][j]][i]++;
                col[p[i][j]][j]++;
            }
        }
        scanf("%d",&q);
        while (q--)
        {
            int x0,x1,y0,y1;
            scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
            int x2=x1+1,y2=y1+1;
            while ((x2-x0)%k!=0) x2--;
            while ((y2-y0)%k!=0) y2--;
            for (int i=0;i<l;i++)
            {
                s[i]=(ll)r[i]*(ll)((x2-x0)/k)*((y2-y0)/k);
            }
            for (int i=x2;i<=x1;i++)
            {
                for (int j=0;j<l;j++)
                {
                    s[j]+=(ll)row[j][i%k]*((y2-y0)/k);
                }
            }
            for (int i=y2;i<=y1;i++)
            {
                for (int j=0;j<l;j++)
                {
                    s[j]+=(ll)col[j][i%k]*((x2-x0)/k);
                }
            }
            for (int i=x2;i<=x1;i++)
            {
                for (int j=y2;j<=y1;j++)
                {
                    s[p[i%k][j%k]]++;
                }
            }
            ll ans=0;
            for (int i=0;i<l;i++)
            {
                ans+=(ll)a[i]*s[i];
            }
            printf("%lld\n",ans);
        }
    }
    return 0;
}

 

1010:愉快的暴力题,先对行暴力,时间复杂度 O(4*4^5*16),每行只有两种可行的情况,再判断列并取最小值即可

solved by lyy

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define per(i,j,k) for (int i=j;i<k;i++)
int t;
char a[20][20];
int vis[1000];

struct st
{
    int num;
    int data[4][16];
};

init()
{
    vis['0']=0;
    vis['1']=0;
    vis['2']=0;
    vis['3']=0;
    vis['4']=0;
    vis['5']=0;
    vis['6']=0;
    vis['7']=0;
    vis['8']=0;
    vis['9']=0;
    vis['A']=0;
    vis['B']=0;
    vis['C']=0;
    vis['D']=0;
    vis['E']=0;
    vis['F']=0;
}

void change(st &s,int x,int y)
{
    int a[4][4];
    int b[4][4];
    for (int i=0;i<4;i++)
    {
        for (int j=0;j<4;j++)
        {
            b[i][j]=s.data[i+x][j+y];
        }
    }
    a[0][0] = b[3][0];
    a[0][1] = b[2][0];
    a[0][2] = b[1][0];
    a[0][3] = b[0][0];
    a[1][0] = b[3][1];
    a[2][0] = b[3][2];
    a[3][0] = b[3][3];
    a[3][1] = b[2][3];
    a[3][2] = b[1][3];
    a[3][3] = b[0][3];
    a[1][1] = b[2][1];
    a[1][2] = b[1][1];
    a[2][2] = b[1][2];
    a[2][1] = b[2][2];
    a[1][3] = b[0][1];
    a[2][3] = b[0][2];
    for (int i=0;i<4;i++)
    {
        for (int j=0;j<4;j++)
        {
            s.data[i+x][j+y]=a[i][j];
        }
    }
}

vector<st> go(int r)
{
    vector<st> ans;
    st x;
    for (int i=0;i<4;i++)
    {
        for (int j=0;j<16;j++)
        {
            x.data[i][j]=a[i+r*4][j];
        }
    }
    per(x1,0,4)
    {
        per(x2,0,4)
        {
            per(x3,0,4)
            {
                per(x4,0,4)
                {
                    int can=1;
                    for (int i=0;i<4;i++)
                    {
                        init();
                        for (int j=0;j<16;j++)
                        {
                            if (vis[x.data[i][j]]==1) can=0;
                            else vis[x.data[i][j]]=1;
                        }
                    }
                    if (can==1)
                    {
                        //cout<<x1<<' '<<x2<<' '<<x3<<' '<<x4<<endl; 
                        x.num=x1+x2+x3+x4;
                        ans.push_back(x);
                    }
                    change(x,0,12);
                }
                change(x,0,8);
            }
            change(x,0,4);
        }
        change(x,0,0);
    }
    return ans;
}

int main()
{
    scanf("%d",&t);
    while (t--)
    {
        for (int i=0;i<16;i++)
        {
            scanf("%s",a[i]);
        }
        vector<st> v1=go(0);
        vector<st> v2=go(1);
        vector<st> v3=go(2);
        vector<st> v4=go(3);
        int ans=10000;
        for (auto x1:v1)
        {
            for (auto x2:v2)
            {
                for (auto x3:v3)
                {
                    for (auto x4:v4)
                    {
                        int can=1;
                        for (int i=0;i<16;i++)
                        {
                            init();
                            for (int j=0;j<4;j++)
                            {
                                if (vis[x1.data[j][i]]==1) can=0;
                                else vis[x1.data[j][i]]=1;
                            }
                            for (int j=0;j<4;j++)
                            {
                                if (vis[x2.data[j][i]]==1) can=0;
                                else vis[x2.data[j][i]]=1;
                            }
                            for (int j=0;j<4;j++)
                            {
                                if (vis[x3.data[j][i]]==1) can=0;
                                else vis[x3.data[j][i]]=1;
                            }
                            for (int j=0;j<4;j++)
                            {
                                if (vis[x4.data[j][i]]==1) can=0;
                                else vis[x4.data[j][i]]=1;
                            }
                            if (can==1)
                            {
                                ans=min(ans,x1.num+x2.num+x3.num+x4.num);
                            }
                        }
                    }
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值