The 2016 ACM-ICPC Asia Dalian Regional Contest

一共a了6题

A:找二分图,判断有没有冲突或者孤立的店

题解:直接dfs即可

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cassert>
#include<iomanip>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

const double g=10.0,eps=1e-7;
const int N=1000+10,maxn=1000+10,inf=0x3f3f3f;

int color[N],n;
vector<int>v[N];
bool dfs(int u,int c)
{
    color[u]=c;
    for(int i=0;i<v[u].size();i++)
    {
        int x=v[u][i];
        if(color[x]==c||(color[x]==0&&!dfs(x,3-c)))
            return 0;
    }
    return 1;
}
void solve()
{
    for(int i=1; i<=n; i++)
    {
        if(color[i]==1&&!dfs(i,1))
        {
            cout<<"NO"<<endl;
            return ;
        }
        else if(color[i]==2&&!dfs(i,2))
        {
            cout<<"NO"<<endl;
            return ;
        }
    }
    for(int i=1; i<=n; i++)
    {
        if(color[i]==0&&!dfs(i,1))
        {
            cout<<"NO"<<endl;
            return ;
        }
    }
    for(int i=1;i<=n;i++)
        if(color[i]==-1)
        {
            cout<<"NO"<<endl;
            return ;
        }
    cout<<"YES"<<endl;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int m,x,y;
    while(cin>>n>>m>>x>>y)
    {
        for(int i=1;i<=n;i++)v[i].clear();
        memset(color,-1,sizeof color);
        while(m--)
        {
            int a,b;
            cin>>a>>b;
            color[a]=color[b]=0;
            v[a].push_back(b);
            v[b].push_back(a);
        }
        for(int i=1;i<=x;i++)
        {
            int a;
            cin>>a;
            color[a]=1;
        }
        for(int i=1;i<=y;i++)
        {
            int a;
            cin>>a;
            color[a]=2;
        }
        solve();
    }
    return 0;
}
/*********************
5 4 1 2
1 3
1 4
3 5
4 5
2
1 3
*********************/
A

D:给你a,b,看能不能找到x,y使x+y==a,最小公约数(x,y)==b

题解:y=a-x,然后gcd(x,y)==gcd(a,b),看二元一次方程有没有解

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1

using namespace std;

const double g=10.0,eps=1e-7;
const int N=2000+10,maxn=60000+10,inf=0x3f3f3f3f;

map<ll,ll>m;
int main()
{
    for(ll i=0;i<=30000;i++)m[i*i]=i;
    ll a,b;
    while(~scanf("%lld%lld",&a,&b))
    {
        ll y=-a,z=__gcd(a,b)*b;
        if(y*y<4*z)puts("No Solution");
        else
        {
            if(!m[y*y-4*z]&&y*y-4*z!=0)puts("No Solution");
            else
            {
                ll p1=-y+m[y*y-4*z],p2=-y-m[y*y-4*z];
                if(p1%2==0&&p1/2>0&&p2%2==0&&p2/2>0)printf("%lld %lld
",min(p1/2,p2/2),max(p1/2,p2/2));
                else puts("No Solution");
            }
        }
    }
    return 0;
}
View Code

F:给一个数a,找一堆不相同的数相加为a,使他们相乘最大

题解:直觉。。。2+3+。。+一直加到和大于a为止,然后把最后一位变成2+3+4+5+6+10这种形式,然后把10平摊到前面 的数2+4+5+6+7+8,然后前缀和二分,答案用前缀积+逆元求

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1

using namespace std;

const double g=10.0,eps=1e-9;
const int N=200000+10,maxn=500+10,inf=40000000;

ll f[N],ans[N];
ll quick(ll a,ll b)
{
    ll ans=1;
    while(b)
    {
        if(b&1)ans=(ans*a)%mod;
        a=(a*a)%mod;
        b/=2;
    }
    return ans;
}
int main()
{
    ans[0]=1;
    for(ll i=1;i<=100000;i++)
    {
        f[i]=i*(i+1)/2-1;
        ans[i]=ans[i-1]*i%mod;
    }
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ll x;
        scanf("%lld",&x);
        if(x<=4)printf("%lld
",x);
        else
        {
            ll p=lower_bound(f,f+100000,x)-f;
            if(f[p]==x)printf("%lld
",ans[p]);
            else
            {
                if(p-x+f[p-1]!=1)printf("%lld
",ans[p]*quick(p-x+f[p-1],mod-2)%mod);
                else printf("%lld
",ans[p+1]*quick(p,mod-2)%mod*quick(2,mod-2)%mod);
            }
        }
    }
    return 0;
}
F

H:一个袋子里有n个红球,1个黑球,二个人轮流拿(拿到不放回),拿到黑球算赢,问先拿的人能不能赢

题解:找规律,emmm当n为奇数,可以看出概率为1/2,n为偶数时,把取的整个过程看成全排列那么就是(n+1)!,分成黑球在奇数位和在偶数位,在奇数位就是先手取的情况,

那么概率就是n+2/(2*(n+1)),保证大于0.5

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1

using namespace std;

const double g=10.0,eps=1e-9;
const int N=200000+10,maxn=500+10,inf=40000000;

int main()
{
    int k;
    while(~scanf("%d",&k))
    {
        if(k&1)puts("0");
        else puts("1");
    }
    return 0;
}
H

I水题

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1

using namespace std;

const double g=10.0,eps=1e-9;
const int N=200000+10,maxn=500+10,inf=40000000;

int main()
{
    int n,d;
    while(~scanf("%d%d",&n,&d))
    {
        double ans=0;
        for(int i=0;i<n;i++)
        {
            double ang;
            scanf("%lf",&ang);
            ans+=sin(ang/180*pi)/2*d*d;
        }
        printf("%.3f
",ans);
    }
    return 0;
}
I

J主要是题意难懂= =,给一堆数,把他化成32位的二进制,然后每8个算一个数(字符),求a的个数,模拟即可

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1

using namespace std;

const double g=10.0,eps=1e-9;
const int N=200000+10,maxn=500+10,inf=40000000;

int main()
{
    int n,d;
    while(~scanf("%d",&n))
    {
        string a="";
        for(int i=0;i<n;i++)
        {
            ll x;
            scanf("%lld",&x);
            string p="";
            for(int j=1;j<=32;j++)
            {
                if(x&1)p+='1';
                else p+='0';
                x/=2;
            }
            reverse(p.begin(),p.end());
            a+=p;
        }
        ll ans=0;
        for(int i=0;i<a.size();i+=8)
        {
            ll p=0;
            for(int j=7;j>=0;j--)p+=(1<<(7-j))*(int)(a[j+i]-'0');
            if((char)p=='a')ans++;
        }
        printf("%d
",ans);
    }
    return 0;
}
J
原文地址:https://www.cnblogs.com/acjiumeng/p/7637947.html