2016ACM/ICPC亚洲区大连站-重现赛(感谢大连海事大学)(6/10)

1001题意:n个人,给m对敌对关系,X个好人,Y个坏人。现在问你是否每个人都是要么是好人,要么是坏人。

先看看与X,Y个人有联通的人是否有矛盾,没有矛盾的话咋就继续遍历那些不确定的人关系,随便取一个数3,与其相连的就是4,间隔就要相同,dfs搜过去就可以判断了

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double Pi = acos(-1.0);
const int N = 5e5+10, maxn = 1e3+20, mod = 1e9+7, inf = 2e9;

int vis[N],t,head[N],n,m,x,y,z,cal[N],xx[N],yy[N];
int flag;
struct ss{
int to,next;}e[N * 2];
void add(int u,int v) {e[t].next = head[u]; e[t].to = v; head[u] = t++;}

void dfs(int u,int fa) {
        cal[u] = 1;
        for(int i = head[u]; i!=-1; i = e[i].next) {
            int to = e[i].to;
            if(to == fa) continue;
            if(vis[u] == 0) vis[u] = 3;
            if(vis[to] == vis[u]) {
                flag = 1;
                return ;
            }
            if(cal[to]) continue;
            if(vis[u] == 3) vis[to] = 4;
            else if(vis[u] == 4) vis[to] = 3;
            else if(vis[u] == 1) vis[to] = 2;
            else if(vis[u] == 2) vis[to] = 1;
            dfs(to,u);
        }
}

int main() {
        while(scanf("%d%d%d%d",&n,&m,&x,&y)!=EOF) {
                t = 1;
        memset(head,-1,sizeof(head));
            for(int i = 1; i <= m; ++i) {
                int a,b;
                scanf("%d%d",&a,&b);
                add(a,b);
                add(b,a);
            }
            memset(cal,0,sizeof(cal));
            memset(vis,0,sizeof(vis));
            for(int i = 1; i <= x; ++i) scanf("%d",&xx[i]),vis[xx[i]] = 1;
            for(int i = 1; i <= y; ++i) scanf("%d",&yy[i]),vis[yy[i]] = 2;
            flag = 0;
            for(int i = 1; i <= x; ++i) {
                if(!cal[i]) dfs(xx[i],-1);
            }
            for(int i = 1; i <= y; ++i) {
                if(!cal[i]) dfs(yy[i],-1);
            }
            if(flag) {
                puts("NO");
                continue;
            }
            for(int i = 1; i<= n; ++i) {
                if(!cal[i]) {
                    dfs(i,-1);
                }
            }
            for(int i = 1; i <= n; ++i) {
                if(!vis[i]) flag = 1;
            }
            if(flag) puts("NO");
            else puts("YES");
        }
        return 0;
}

1001

1003题意:两堆石子,你可以任选一堆去掉任意个数,你也可从两堆中同时去掉任意个数,最后全部取完的人胜

石子的数量是10^100.高精度的威佐夫博弈,需要黄金比例精确到100位,队友javaA。

import java.util.*;
import java.math.*;

public class Main {
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        BigInteger k=new BigInteger("6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374");
        BigInteger p=new BigInteger("10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
        while(cin.hasNext())
        {
            BigInteger nn=cin.nextBigInteger();
            BigInteger mm=cin.nextBigInteger();
            BigInteger n=nn.min(mm);
            BigInteger m=nn.max(mm);
            BigInteger j=n.multiply(k);
            j=j.divide(p);
            BigInteger l=j.multiply(k.add(new BigInteger("1")));
            l=l.divide(p);
            if(n.equals(l)==false)
                j=j.add(new BigInteger("1"));
            n=n.add(j);
            if(n.equals(m))
                System.out.println("0");
            else
                System.out.println("1");
        }
    }
}

1003

1004题意:给定a,b; 求出满足 LCM(X,Y) = b && X+Y = a的一组解,或者是无解

公式转化:b*gcd(X,Y) = X*Y,X+Y=a;

我们可以知道gcd(X,Y) 必然是a的因子!,那么我们为了枚举gcd(X,Y)就直接去枚举a的因子就是了

枚举以后就相当于求解一个二元一次方程的整数解了;

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double Pi = acos(-1.0);
const int N = 5e5+10, maxn = 1e3+20, mod = 1e9+7, inf = 2e9;

LL a,b,p[N],ans1,ans2;
int ok;

int check(LL a,LL B,LL gc) {
            if(a*a - 4*B < 0) return 0;
            LL tmp = (int)(sqrt(a*a - 4*B)+0.00001);
            if(tmp*tmp != a*a - 4*B) return 0;

            LL fi = a+tmp;
            if(fi>=0&&fi%2==0) fi/=2;
            else fi = -1;

            LL se = a-tmp;
            if(se>=0&&se%2==0) se/=2;
            else se = -1;
            if(fi <= 0 && se <= 0) return 0;
            if(fi > 0) {
                    LL x = a - fi;
                    if((__gcd(fi,x)==gc)&&x * fi == B) {
                        ans1 = fi,ans2 = x;
                        if(ans1>ans2)
                            swap(ans1,ans2);
                        ok = 1;
                        return 1;
                    }
                }
                 if(se > 0) {
                    LL x = a - se;
                    if((__gcd(x,se)==gc)&&x * se == B) {
                        ans1 = se,ans2 = x;
                        if(ans1>ans2)
                            swap(ans1,ans2);
                        ok = 1;
                        return 1;
                    }
                }
                return 0;
}
int main() {
        while(scanf("%I64d%I64d",&a,&b)!=EOF) {
            ok = 0;
            for(int i = 1; i * i <= a; ++i) {
                if(a % i == 0) {
                    if(check(a,b*i,i)) break;
                    if(check(a,b*(a/i),a/i)) break;
                }
            }
            if(ok) printf("%I64d %I64d\n",ans1,ans2);
            else puts("No Solution");
        }
}

1004

1006题意:给你一个x,然后你要构造一个数组a,满足∑a = x, 任意的i,j( i != j) a[i] != a[j];问你 最大的 s = a1*a2*a3*......*an是多少;

要使得乘积最大,那么相乘的数越多显然S是越大的。。。。

假设x = 7, 那么我们构造出一个数组   2 3 2,到这里有重复的数了,我们就把最后面的2平分到前面  2,3 -> 3,4

假设x = 8,那么我们构造出一个数组   2 3 3,到这里有重复的数了,我们就把最后面的3平分到前面  2,3 -> 3,4 到这里,还有一个1,我们就分到最后一个数上去 -> 3 5

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long ll;
const long long INF = 1e18+1LL;
const double Pi = acos(-1.0);
const int N = 5e5+10, maxn = 1e3+20, mod = 1e9+7, inf = 2e9;
ll sum[N];
ll pre[N];
ll quick_pow(ll x,ll y)
{
    ll ans=1;
    while(y)
    {
        if(y&1)ans*=x,ans%=mod;
        y>>=1;
        x*=x;
        x%=mod;
    }
    return ans;
}
int main() {
        sum[1]=2;
        for(int i = 2;i<44725 ; ++i) {
                sum[i]=sum[i-1]+i+1;
        }

    int cnt=44720,T;
    pre[0]=1;
    for(int i=1;i<44725;i++)
        {
            pre[i]=(pre[i-1]*(i+1))%mod;
        }
    scanf("%d",&T);
    while(T--)
    {
        ll x;
        scanf("%lld",&x);
        if(x == 1LL) {
            puts("1");
            continue;
        }
        int pos=upper_bound(sum+1,sum+cnt+1,x)-sum-1;
        ll m=x-sum[pos];
        if(m == pos+1) {
            ll ans=pre[pos];
            ans=(ans*(pos+3))%mod;
            ans=(ans*quick_pow(2,mod-2))%mod;
            printf("%lld\n",ans);
            continue;
        }
        ll ans = pre[pos - m];
        if(m!=0) ans = ans * ((pre[pos+1]*quick_pow((pre[pos-m+1]),mod-2))% mod )% mod;
        if(x==1)
            printf("1\n");
        else
        printf("%lld\n",ans);
    }
    return 0;
}

1006

1008题意:k个黑球,1个白球,每次每人只能取一球,先取到红球的人胜利,问先取的人是否为有利,或者是平等

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi (4*atan(1.0))
#define eps 1e-14
const int N=2e5+10,M=4e6+10,inf=1e9+10,mod=1e9+7;
const ll INF=1e18+10,MOD=1e9+7;
int main()
{
    int x;
    while(~scanf("%d",&x))
    {
        if(x&1)
            printf("0\n");
        else
            printf("1\n");
    }
    return 0;
}

1008

1009题意:N个角度,长度为D,求出这n个线段围成的面积

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double Pi = acos(-1.0);
const int N = 4e5+10, maxn = 1e3+20, mod = 1e9+7, inf = 2e9;

double d;
int n;
int main() {
        while(scanf("%d%lf",&n,&d)!=EOF) {
                double ans = 0.0;
                double x;
                for(int i = 1; i <= n; ++i) {
                    scanf("%lf",&x);
                    ans += d*d*sin(x/180 * Pi)/2;
                }
                printf("%.3f\n",ans);
        }
    return 0;
}

1009

  

时间: 2024-10-09 19:51:52

2016ACM/ICPC亚洲区大连站-重现赛(感谢大连海事大学)(6/10)的相关文章

2016ACM/ICPC亚洲区大连站-重现赛

题目链接:http://acm.hdu.edu.cn/search.php?field=problem&key=2016ACM%2FICPC%D1%C7%D6%DE%C7%F8%B4%F3%C1%AC%D5%BE-%D6%D8%CF%D6%C8%FC%A3%A8%B8%D0%D0%BB%B4%F3%C1%AC%BA%A3%CA%C2%B4%F3%D1%A7%A3%A9&source=1&searchmode=source A.染色乱搞. 1 #include <bits/st

2016ACM/ICPC亚洲区沈阳站-重现赛

C.Recursive sequence 求ans(x),ans(1)=a,ans(2)=b,ans(n)=ans(n-2)*2+ans(n-1)+n^4 如果直接就去解...很难,毕竟不是那种可以直接化成矩阵的格式,我们也因为这个被卡很长时间 事实上可以把这道式子化成几个基本元素的格式,然后就容易组合了,比如ans(n-2)*2+ans(n-1)+(n-1)^4+4*(n-1)^3+6*(n-1)^2+4*(n-1)^1+1 包含了所有的基本组成形式,化绝对为相对,并且除了一个n-2其他都是n

2016 ACM/ICPC亚洲区大连站-重现赛 解题报告

任意门:http://acm.hdu.edu.cn/showproblem.php?pid=5979 按AC顺序: I - Convex Time limit    1000 ms Memory limit 65536 kB OS Windows We have a special convex that all points have the same distance to origin point. As you know we can get N segments after linki

HDU 5976 Detachment 【贪心】 (2016ACM/ICPC亚洲区大连站)

Detachment Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 570    Accepted Submission(s): 192 Problem Description In a highly developed alien society, the habitats are almost infinite dimensiona

hdu5512 Pagodas(2015ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学) )

Pagodas Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 14 Accepted Submission(s): 13 Problem Description n pagodas were standing erect in Hong Jue Si between the Niushou Mountain and the Yuntai M

2017ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)HDU6225.Little Boxes-大数加法

整理代码... Little Boxes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 2304    Accepted Submission(s): 818 Problem Description Little boxes on the hillside.Little boxes made of ticky-tacky.Littl

hdu 5510 Bazinga (kmp+dfs剪枝) 2015ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)

废话: 这道题很是花了我一番功夫.首先,我不会kmp算法,还专门学了一下这个算法.其次,即使会用kmp,但是如果暴力枚举的话,还是毫无疑问会爆掉.因此在dfs的基础上加上两次剪枝解决了这道题. 题意: 我没有读题,只是队友给我解释了题意,然后我根据题意写的题. 大概意思是给n个字符串,从上到下依次标记为1——n,寻找一个标记最大的串,要求这个串满足:标记比它小的串中至少有一个不是它的子串. 输入: 第一行输入一个整型t,表示共有t组数据. 每组数据首行一个整型n,表示有n个串. 接下来n行,每行

2015ACM/ICPC亚洲区沈阳站-重现赛 1004 Pagodas

Problem Description: n pagodas were standing erect in Hong Jue Si between the Niushou Mountain and the Yuntai Mountain, labelled from 1 to n. However, only two of them (labelled aand b, where 1≤a≠b≤n) withstood the test of time. Two monks, Yuwgna and

【hdu 5521】【 2015ACM/ICPC亚洲区沈阳站重现赛】Meeting 题意&题解&代码

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5521 题意: 输入:输入n表示有n个点,输入m表示有m个点集. 接下来m行信息,每行先输入一个t表示这个点集中任意两点费时为t,再输入一个s,表示有s个点在这个点集中,接下来s个数表示这些数在这个点集之中. 现在有两个人,其中一个人住在点1,另一个人住在点n,如果两个人要见面,同时出发,可以走走停停,问需要最少时间是多少,有哪几个点能被当成见面点. 题解: 我们发现这道题如果建好图之后就直接是一个