赛码"BestCoder"杯中国大学生程序设计冠军赛

渣渣一枚



总共做了4个题目.先总结下吧.题目质量很高.

题目链接

1001

这个题目第一眼就是hdu之前的题目今年暑假不AC.只选三个,那么就是左右两边贪心取优.

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define MOD 4294967296

using namespace std;
typedef unsigned int LL;
int T;
int n;
const int N=10000005;
LL s1,e1;
LL L1,R1,L2,R2;
LL minL,minR,maxL,maxR;
LL a,b,c,d;
LL p[N],q[N];
bool flag;
int main()
{
  #ifdef ONLINE_JUDGE
  #else
    freopen("test.in","r",stdin);
  #endif
  scanf("%d",&T);
  while(T--)
  {
    cin>>n>>s1>>e1>>a>>b>>c>>d;
    p[1]=s1;
    q[1]=e1;
    for(int i=2;i<=n;i++)
    {
      p[i]=p[i-1]*a+b;
      q[i]=q[i-1]*c+d;
    }
    for(int i=1;i<=n;i++)
    {
      if(p[i]>q[i])
      {
        swap(p[i],q[i]);
      }
      if(i==1)
      {
        minL=maxL=p[1];
        minR=maxR=q[1];
      }
      else
      {
        if(q[i]<minR)
        {
          minL=p[i];
          minR=q[i];
        }
        if(p[i]>maxL)
        {
          maxL=p[i];
          maxR=q[i];
        }
      }
    }
    flag=false;
    for(int i=1;i<=n;i++)
    {
      if(p[i]>minR&&q[i]<maxL)
      {
        flag=true;
        break;
      }
    }
    printf("%s\n",flag?"YES":"NO");
  }
  return 0;
}

1005

这道是递推题目,着实学了一下,思路和HDU4089很像.这个递推没想出来有点伤心.当有1个人的时候情况可知,那么人数更多的时候可以推过来,于是 dp[i][j] 当有i个人时,j能否赢.O(n3)

Tips: 当有环或取模时,编号从0开始,避免了整除等情况特殊处理.

#include "stdio.h"
#include "iostream"
#include "string.h"
#include "stdlib.h"
#include "algorithm"
#include "math.h"
#include <queue>
using namespace std;
const int MAXN=210;

int dp[MAXN][MAXN];
typedef long long LL;
int a[MAXN];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i = 1;i<=m;i++) scanf("%d",a+i);
        memset(dp,0,sizeof(dp));
        dp[1][0] = 1;
        for(int i = 2;i<=n;i++){
            for(int j = 0;j<n;j++) if(dp[i-1][j])
                for(int k = 1;k<=m;k++)
                    dp[i][ (j+a[k])%i   ] = 1;
        }
        int cnt = 0;
        for(int i = 0;i<n;i++) if(dp[n][i])
            a[cnt++] = i+1;
        printf("%d\n",cnt);
        for(int i = 0;i<cnt;i++)
            if(i==cnt-1) printf("%d\n",a[i]);
            else printf("%d ",a[i]);
    }
    return 0;
}

1009

图论都忘完了,这里所有的边都只能走一次,我卡在了双向边要考虑两个点的先后顺序,孰不知这个直接并查集合并即可,就能当作一个点来用了.这样若接收的点在同一集合就YES.不然就变成了DAG,拓扑排序即可.PS: bfs的拓扑排序很好用,以前用两层循环写的太恶心了.

#include "stdio.h"
#include "iostream"
#include "string.h"
#include "stdlib.h"
#include "algorithm"
#include "math.h"
#include <queue>
using namespace std;
const int MAXN=1000005;
const int MAXV=1010000;

int pre[MAXV],m,a,b;
bool root[MAXV];

typedef long long LL;

int ned,ans,fa[MAXN],son[MAXN];
int n,m1,m2;
queue<int> q;
int mm1[MAXN][2],mm2[MAXN];

struct EDGE{
    int p;
    struct EDGE *nex;
}edge[2*MAXN],*head[MAXN];

void init()
{
    if(!q.empty())
        q.pop();
    ned=0;
    for(int i=0;i<MAXN;i++)
        head[i]=NULL;
    memset(son,0,sizeof(son));
    memset(mm1,0,sizeof(mm1));
    memset(mm2,0,sizeof(mm2));
    for(int i=1;i<=MAXN;i++)
        pre[i]=i;
    memset(root,0,sizeof(root));
    ans=0;
}

void addedge(int s,int e)
{
    edge[ned].p=e;edge[ned].nex=head[s];
    head[s]=&edge[ned];
    ned++;
}

int find(int x)
{
    int r=pre[x];
    while(pre[r]!=r)
        r=pre[r];
    int i=x,j;
    while(pre[i]!=i)                     //压缩路径优化
    {
        j=pre[i];
        pre[i]=r;
        i=j;
    }
    return r;
}

void join(int x,int y)
{
    int fx=find(x),fy=find(y);
    if(fx!=fy)
        pre[fy]=fx;
}

int main()
{
    int flag;
    int T;
    cin>>T;
    while(T--)
    {
        flag=0;
        init();
        cin>>n>>m2>>m1;
        int aa,bb;

        for(int i=0;i<m2;i++)
        {
            scanf("%d%d",&aa,&bb);
            if(find(aa)==find(bb))
            {
                flag=1;
            }
            else
            {
                join(aa,bb);
            }
        }

        for(int i=0;i<m1;i++)
        {
            scanf("%d%d",&mm1[i][0],&mm1[i][1]);
        }

        for(int i=0;i<m1;i++)
        {
            aa=find(mm1[i][0]);
            bb=find(mm1[i][1]);
            if(aa==bb)
            {
                flag=1;
                break;
            }
            else
            {
                addedge(aa,bb);
            }
        }
        if(flag==1)
        {
            printf("YES\n");
            continue;
        }
        memset(fa,0,sizeof(fa));
        for(int i=0;i<ned;i++)
        {
            fa[edge[i].p]++;
        }
        for(int i=1;i<=n;i++)
        {
            if(fa[i]==0)
            {
                q.push(i);
            }
        }
        while(!q.empty())
        {
            int x=q.front(),f;
            q.pop();
            for(struct EDGE *w=head[x];w!=NULL;w=w->nex)
            {
                int x=w->p;
                fa[x]--;
                if(fa[x]==0)
                    q.push(x);
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(fa[i]!=0)
            {
                flag=1;
                break;
            }
        }
        if(flag)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

1010

这个是大水题,刚开始看的时候被多个数的GCD下尿了.后来一想问题不重叠对区域是1,重叠的区域取多个区域数的LCM即可.什么时候不和要求? 范围大GCD反而大,范围相等却GCD不等,只想到这两种….

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define MAXN 1101

using namespace std;

struct P{
    int l,r,x;
    bool operator < (const P &a) const{
        if(l==a.l) return r<a.r;
        return l<a.l;

    }
}p[MAXN];
long long a[MAXN];
long long GCD(long long a,long long b){
    return b==0?a:GCD(b,a%b);
}
int main() {
    int T,N,Q;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&N,&Q);
        for(int i = 1;i<=Q;i++)
            scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].x);
        int tag = 1;
        for(int i = 1;i<=Q && tag;i++){
            for(int j = 1;j<=Q && tag;j++){
                if(p[i].l==p[j].l && p[i].r==p[j].r && p[i].x != p[j].x)
                    tag = 0;
                if(p[i].l>p[j].l && p[i].r<p[j].r && p[i].x < p[j].x)
                    tag = 0;
            }
        }
        if(tag==0){
            printf("Stupid BrotherK!\n");
            continue;
        }
        for(int i = 1;i<=N;i++) a[i] = 1;
        for(int i = 1;i<=N;i++){
            for(int j = 1;j<=Q;j++) if(i>=p[j].l && i<=p[j].r)
                a[i] = a[i] / GCD(a[i],p[j].x) * p[j].x;
        }

        for(int i = 1;i<=N;i++)
            if(i==N) printf("%I64d\n",a[i]);
            else printf("%I64d ",a[i]);

    }
    return 0;
}
时间: 2024-11-08 09:51:32

赛码"BestCoder"杯中国大学生程序设计冠军赛的相关文章

ACM 五一杭电赛码&quot;BestCoder&quot;杯中国大学生程序设计冠军赛小记

对于这项曾经热爱的竞赛,不得不说这是我最后一年参加ACM比赛了,所以要珍惜每一次比赛的机会. 五一去杭电参加了赛码"BestCoder"杯中国大学生程序设计冠军赛,去的队伍包括了今年19支World final的队伍,几乎是全国最强的46所学校各出了一个代表队,十分感谢学校给了我这个大三的老年血手这次去比赛的机会. 比赛在5.2一天内完成,上午的热身赛居然是上一场Bestcoder的原题= =.虽然我们三个人都没做过...不过我还是水水的写了前两道题. 在中午的悲惨淋雨后,下午正赛开始

(赛码&quot;BestCoder&quot;杯中国大学生程序设计冠军赛)GCD

GCD Accepts: 433 Submissions: 1753 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Problem Description In mathematics, the greatest common divisor (gcd) of two or more integers, when at least one of them is not zero

HDU 5214 Movie (赛码&quot;BestCoder&quot;杯中国大学生程序设计冠军赛A题)

五一有幸跟着老师去了一次杭电,求虐之行,坐等清华北大等巨巨AK全场,总结经验,激励前进! [题目链接]click here~~ [题目大意]在多个不确定区间里面,问能否选出三个互不相交的区间 [解题思路]  ps:当时是hjs敲题,敲完之后三个人都检查了一遍,发现没有问题,但是交上去却CE了,后面于是各种调,各种错误,最后发现把取模去掉,直接判断一下是否存在一个区间位于已经出来的区间中间且不交叉即可,悲剧... [官方解题报告]首先我们考虑如何选择最左边的一个区间,假设最左边的区间标号是i, 那

赛码&quot;BestCoder&quot;杯中国大学生程序设计冠军赛1009——邻接表+并查集——Exploration

Problem Description Miceren likes exploration and he found a huge labyrinth underground! This labyrinth has N caves and some tunnels connecting some pairs of caves. There are two types of tunnel, one type of them can be passed in only one direction a

赛码&quot;BestCoder&quot;杯中国大学生程序设计冠军赛1001——Movie

Problem Description Cloud and Miceren like watching movies. Today, they want to choose some wonderful scenes from a movie. A movie has N scenes can be chosen, and each scene is associate with an interval [L, R]. L is the beginning time of the scene a

&quot;BestCoder&quot;杯中国大学生程序设计冠军赛 HDU 5221 Occupation

题目链接~~> 做题感悟 :区域赛过后就没写过树剖 ,只记得思想,比赛时想到了,但是只打代码就打了半个多小时(真是醉了!!),然后就是不断的调试代码,悲催的是调了一个多小时也没调出来..... 解题思路:这题只要想到某个节点的子树的所有节点编号都大于此节点的编号(在线段树中)且是连续的,那么我们只要深搜的时候记录一下子树最大的一个节点的时间戳(在线段树中的编号),只要我们利用一个节点的进去的时间戳和出去的时间戳就可以对这个节点的子树操作了(CF上有一个处理子树类似的题),其它的两个操作就 so

第八届福建省大学生程序设计竞赛-重现赛

第八届福建省大学生程序设计竞赛-重现赛 B   计算几何 题意:问两个三角形是相交.包含还是相离. tags:套板子..求出相交的面积,再判断一下 /* 多边形相交面积模板 */ #define maxn 510 const double eps=1E-8; int sig(double d){ return(d>eps)-(d<-eps); } struct Point{ double x,y; Point(){} Point(double x,double y):x(x),y(y){} b

第39届ACM国际大学生程序设计竞赛 亚洲区域赛(现场赛)西安站

 第39届ACM国际大学生程序设计竞赛 亚洲区域赛(现场赛)西安赛区总结报告 报告人:田思明 队名:ACpioneer 队长:陈志阳,队员:顾振兴,田思明 西安区域赛告下帷幕,我和陈志阳,顾振兴组成的ACpioneer队最终获得了一块宝贵的铜牌.首先要感谢陈志阳和顾振兴两位杰出队友的努力训练和出色表现,我作为一个新人跟着他们学到了很多很多,也十分珍惜和他们在一起的训练,比赛时光,其次要感谢陈志老师,不辞辛劳陪我们5队和6队前往西安参加比赛,还要感谢集训队所有曾经帮过我们的所有队员们,记得cdy

2016年中国大学生程序设计竞赛(合肥)-重现赛1008 HDU 5968

异或密码 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 19    Accepted Submission(s): 9 Problem Description 晨晨在纸上写了一个长度为N的非负整数序列{ai }.对于这个序列的一个连续子序列{al,al+1,…,ar }晨晨可以求出其中所有数异或的结果 alxoral+1xor...xo