zoukankan      html  css  js  c++  java
  • 2017"百度之星"程序设计大赛

    这套题体验极差。

    PROBLEM 1001 - 小C的倍数问题

      OvO http://acm.hdu.edu.cn/showproblem.php?pid=6108

      (2017"百度之星"程序设计大赛 - 初赛(A) - 1001)

       10进制下,各位数和是9的倍数的数能被9整除是因为 10^k-1=能被9整除

       实质上就是10-1的因数有9

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    
    using namespace std;
    
    int calcu(int spl)
    {
    	int i,j,ret=0;
    	for(i=1;i*i<=spl;i++)
    		if(spl%i==0)
    		{
    			ret++;
    			if(i*i!=spl)
    				ret++;
    		}
    	return ret;
    }
    
    int main()
    {
    	int cas;
    	int p;
    	cin>>cas;
    	while(cas--)
    	{
    		cin>>p;
    		cout<<calcu(p-1)<<endl;
    	}
    	return 0;
    }
    

      

     

    PROBLEM 1002 - 数据分割

      OvO http://acm.hdu.edu.cn/showproblem.php?pid=6109

      (2017"百度之星"程序设计大赛 - 初赛(A) - 1002)

      每次拿到题目给的2个点,如果这两个点是相等的,则把这两个点所在的并查集合并,否则,找到这两个点的根,然后把把这两个根节点连一条边。

      每次合并并查集的时候,要把相连的边也转移(选择边少的那个并查集转移)。

      每次读入2个点,记录这两个点的具体值,存到栈里,以后每次清空,清空栈里这些值对应的位置即可,这样就算要清空L次也不会超时。

      (思路来源于瞟了一眼某个我忘了在哪里的地方)

      

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    
    const int N=2e5+44;
    
    struct node{
        int u,v;
        int next;
    }edge[2*N];
    
    struct clearpair
    {
    	int a,b;
    } ;
    
    queue<clearpair> clearlist;
    int cnt,num;
    int head[N];
    int answer[N],lanswer;
    int fa[N],tol[N],hav[N];
    int t;
    
    void addedge(int u,int v)
    {
        edge[num].u=u;
        edge[num].v=v;
        edge[num].next=head[u];
        head[u]=num++;
    }
    
    void changeedge(int id,int u)
    {
    	edge[id].u=u;
    	edge[id].next=head[u];
    	head[u]=id;
    }
    
    void init(int sz=100000)
    {
    	t=0;
    	num=0;
       	for(int i=1;i<=sz;i++)
    	{
    		head[i]=-1; 
    		fa[i]=i;
    		tol[i]=1;
    	}
    	while(!clearlist.empty())
    		clearlist.pop();
    }
    
    void clear()
    {
    	clearpair tmp;
    	int a,b;
    	t=0; num=0;
    	while(!clearlist.empty())
    	{
    		tmp=clearlist.front();
    		clearlist.pop();
    		head[tmp.a]=-1; fa[tmp.a]=tmp.a; tol[tmp.a]=1;
    		head[tmp.b]=-1; fa[tmp.b]=tmp.b; tol[tmp.b]=1;		
    	}
    }
    
    int fff(int x)
    {
    	if(fa[x]==x)
    		return x;
    	fa[x]=fff(fa[x]);
    	return fa[x];
    }
    
    bool merge(int a,int b)
    {
    	int v,nxttmp,i,j,pa,pb,pv;
    	pa=fff(a); pb=fff(b);
    	if(pa==pb) return true;
    	if(hav[pa]>hav[pb])
    		swap(pa,pb),swap(a,b);
    	hav[pb]+=hav[pa];
    	fa[pa]=pb;
    	for(i=head[pa],nxttmp=edge[i].next;i!=-1;i=nxttmp,nxttmp=edge[i].next)
    	{
    		v=edge[i].v; pv=fff(v);
    		if(pv==pb)
    			return false;
    		changeedge(i,pb);
    	}
    	return true;
    }
    
    bool solve(int a,int b,int c)
    {
    	int pa,pb;
    	if(c==0)
    	{
    		pa=fff(a); pb=fff(b);
    		if(pa==pb) return false;
    		addedge(pa,pb);
    		addedge(pb,pa);
    		return true;
    	}
    	else
    		return merge(a,b);
    }
    
    int main()
    {
    	int i,j,a,b,c;
    	int T;
    	scanf("%d",&T);
    	lanswer=0;
    	init();
    	while(T--)
    	{
    		t++;
    		scanf("%d%d%d",&a,&b,&c);
    		clearlist.push((clearpair){a,b});
    		if(solve(a,b,c)==false)
    		{
    			answer[++lanswer]=t;
    			clear();
    		}
    	}
    	printf("%d
    ",lanswer);
    	for(i=1;i<=lanswer;i++)
    		printf("%d
    ",answer[i]);
    	return 0;
    }
    

      

      

    PROBLEM 1003 - 路径交

      Q∧Q http://acm.hdu.edu.cn/showproblem.php?pid=6110

      (2017"百度之星"程序设计大赛 - 初赛(A) - 1003)

      其实题目求的是[L,R]这个区间的路径的交,(而不是L,R两条的路径交),而且路径交的定义是[L,R]都覆盖的路径,(而不是只要有2条路径覆盖就行),

      开个线段树,线段树中区间[li,ri]对应li~ri这些路径的交。

      求路径交用LCA

      (题意和思路来源于某大佬

    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <cstdio>
    
    using namespace std;
    
    typedef long long ll;
    
    const int MAXN=500044;
    
    int rmq[2*MAXN];//建立RMQ的数组
    
    struct ST
    {
        int mm[2*MAXN];//mm[i]表示i的最高位,mm[1]=0,mm[2]=1,mm[3]=1,mm[4]=2
        int dp[MAXN*2][35];
        void init(int n)
        {
            mm[0]=-1;
            for(int i=1;i<=n;i++)
            {
                mm[i]=((i&(i-1))==0?mm[i-1]+1:mm[i-1]);
                dp[i][0]=i;
            }
            for(int j=1;j<=mm[n];j++)
              for(int i=1;i+(1<<j)-1<=n;i++)
                 dp[i][j]=rmq[dp[i][j-1]]<rmq[dp[i+(1<<(j-1))][j-1]]?dp[i][j-1]:dp[i+(1<<(j-1))][j-1];
        }
        int query(int a,int b)//查询a到b间最小值的下标
        {
            if(a>b)swap(a,b);
            int k=mm[b-a+1];
            return rmq[dp[a][k]]<rmq[dp[b-(1<<k)+1][k]]?dp[a][k]:dp[b-(1<<k)+1][k];
        }
    };
    
    struct Node
    {
        int to,next,val;
    };
    
    struct LCA2RMQ
    {
        int n;//结点个数
        Node edge[2*MAXN];//树的边,因为是建无向边,所以是两倍
        int tol;//边的计数
        int head[MAXN];//头结点
    
        bool vis[MAXN];//访问标记
        int F[2*MAXN];//F是欧拉序列,就是DFS遍历的顺序
        int P[MAXN];//某点在F中第一次出现的位置
        int cnt;
    
        ST st;
        void init(int n)//n为所以点的总个数,可以从0开始,也可以从1开始
        {
            this->n=n;
            tol=0;
            memset(head,-1,sizeof(head));
        }
        void addedge(int a,int b,int val)//加边
        {
            edge[tol].to=b;
            edge[tol].next=head[a];
            edge[tol].val=val;
            head[a]=tol++;
            edge[tol].to=a;
            edge[tol].next=head[b];
            edge[tol].val=val;
            head[b]=tol++;
        }
    
        int query(int a,int b)//传入两个节点,返回他们的LCA编号
        {
            return F[st.query(P[a],P[b])];
        }
    
        void dfs(int a,int lev)
        {
            vis[a]=true;
            ++cnt;//先加,保证F序列和rmq序列从1开始
            F[cnt]=a;//欧拉序列,编号从1开始,共2*n-1个元素
            rmq[cnt]=lev;//rmq数组是深度序列
            P[a]=cnt;
            for(int i=head[a];i!=-1;i=edge[i].next)
            {
                int v=edge[i].to;
                if(vis[v])continue;
                dfs(v,lev+1);
                ++cnt;
                F[cnt]=a;
                rmq[cnt]=lev;
            }
        }
    
        void solve(int root)
        {
            memset(vis,false,sizeof(vis));
            cnt=0;
            dfs(root,0);
            st.init(2*n-1);
        }
    }lca;
    
    struct Line
    {
    	int a,b,flag;
    } line[MAXN],answer[MAXN],tree[MAXN*3];
    
    ll dep[MAXN];
    int lv[MAXN];
    
    bool cmp(int x,int y)
    {
    	return lv[x]>lv[y];
    }
    
    Line merge(Line x,Line y)
    {
    	Line ret; ret.flag=true;
    	if(x.flag==false || y.flag==false)
    	{
    		ret.flag=false;
    		return ret;
    	}
    	int lcax=lca.query(x.a,x.b),lcay=lca.query(y.a,y.b);
    	if(lv[lcax]>lv[lcay])
    		swap(x,y),swap(lcax,lcay);
    	int lca11=lca.query(x.a,y.a),lca12=lca.query(x.a,y.b),lca21=lca.query(x.b,y.a),lca22=lca.query(x.b,y.b);
    	int que[5];
    	que[1]=lca11; que[2]=lca12; que[3]=lca21; que[4]=lca22;
    	sort(que+1,que+4+1,cmp);
    	ret.a=que[1]; ret.b=que[2];
    //	cout<<que[1]<<'-'<<que[2]<<endl;
    	if(lv[ret.a]<lv[lcax] || lv[ret.b]<lv[lcax] || lv[ret.a]<lv[lcay] || lv[ret.b]<lv[lcay]) ret.flag=false;
    //	cout<<ret.a<<' '<<ret.b<<' '<<lcax<<' '<<lcay<<' '<<ret.flag<<endl;
    	return ret;
    }
    
    void build(int rt,int li,int ri)
    {
    	if(li==ri)
    	{
    		tree[rt]=line[ri];
    		return ;
    	}
    	int mid=(li+ri)>>1,lc=(rt<<1),rc=(rt<<1)+1;
    	build(lc,li,mid);
    	build(rc,mid+1,ri);
    	tree[rt]=merge(tree[lc],tree[rc]);
    }
    
    Line query(int rt,int li,int ri,int lq,int rq)	//get Line
    {
    	bool flag=false;
    	Line ret;
    	if(lq<=li && ri<=rq)
    		return tree[rt];
    	int mid=(li+ri)>>1,lc=(rt<<1),rc=(rt<<1)+1;
    	if(mid>=lq)
    	{
    		flag=true;
    		ret=query(lc,li,mid,lq,rq);
    	}
    	if(mid+1<=rq)
    	{
    		if(flag==false)
    			ret=query(rc,mid+1,ri,lq,rq);
    		else
    			ret=merge(ret,query(rc,mid+1,ri,lq,rq));
    	}
    	return ret;
    }
    
    void getdepth(int rt,int pa,ll depnow,int lvnow)
    {
    	int i,j,v;
    	lv[rt]=lvnow;
    	dep[rt]=depnow;
    	for(i=lca.head[rt];i!=-1;i=lca.edge[i].next)
    	{
    		v=lca.edge[i].to;
    		if(v==pa) continue;
    		getdepth(v,rt,depnow+lca.edge[i].val,lvnow+1);
    	}
    }
    
    ll getlength(int a,int b)
    {
    	int c=lca.query(a,b);
    	return dep[a]-dep[c]+dep[b]-dep[c];
    }
    
    inline void read(int &ret)
    {
        int k=0;
        char f=1;
        char c=getchar();
        for(;!isdigit(c);c=getchar() )
            if(c=='-')
                f=-1;
        for(;isdigit(c);c=getchar() )
            k=k*10+c-'0';
        ret=k*f;
    }
    
    int main()
    {
    	int i,j,a,b,c,n,m,q;
    	ll ans;
    	while(scanf("%d",&n)!=EOF)
    	{
    		lca.init(n);
    		for(i=1;i<n;i++)
    		{
    			read(a); read(b); read(c);
    			lca.addedge(a,b,c);
    		}
    		lca.solve(1);
    		getdepth(1,-1,0,0);
    		read(m);
    		for(i=1;i<=m;i++)
    		{
    			read(line[i].a); read(line[i].b);
    			line[i].flag=true;
    		}
    		build(1,1,m);
    		read(q);
    		for(i=1;i<=q;i++)
    		{
    			read(a); read(b);
    			answer[i]=query(1,1,m,a,b);
    		}
    		for(i=1;i<=q;i++)
    		{
    	//		cout<<answer[i].a<<' '<<answer[i].b<<endl;
    			if(answer[i].flag)
    				ans=getlength(answer[i].a,answer[i].b);
    			else
    				ans=0;
    			printf("%lld
    ",ans);
    		}
    	}
    	return 0;
    }
    
    /*
    
    4
    1 2 2000000000
    2 3 2000000000
    1 4 2000000000
    4
    3 4
    3 4
    1 4
    2 3
    4
    1 2
    3 4
    1 3
    1 4
    
    */ 
    

      

     

    PROBLEM 1005 - 小今夕何夕

      OvO http://acm.hdu.edu.cn/showproblem.php?pid=6112

      (2017"百度之星"程序设计大赛 - 初赛(A) - 1005)

       注意2-29

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    
    int a,b,c;
    int id;	
    int inc[3]={1,2};
    
    int jg(int spl)
    {
    	if(spl%400==0)
    		return 1;
    	if(spl%100==0)
    		return 0;
    	if(spl%4==0)
    		return 1;
    	return 0;
    }
    
    int solve()
    {
    	int ret=a+1,i,j,now=0;
    	if(b==2 && c==29)
    	{
    		id=a+1;
    		for(i=id;;i++,ret++)
    		{
    			now+=inc[jg(i)];
    			now%=7;
    			if(jg(i) && now==0)
    				return ret;
    		}
    	}
    	id=a;
    	if(b>2) id++;
    	for(i=id;;i++,ret++)
    	{
    		now+=inc[jg(i)];
    		now%=7;
    //		cout<<"ret: "<<ret<<' '<<"i: "<<i<<' '<<"now: "<<now<<endl;
    		if(now==0)
    			return ret;
    	}
    }
    
    int main()
    {
    	int i,j;
    	int T;
    	cin>>T;
    	while(T--)
    	{
    		scanf("%d-%d-%d",&a,&b,&c);
    		printf("%d
    ",solve());
    	}
    	return 0;
    }
    

      

     

    PROBLEM 1006 - 度度熊的01世界

      OvO http://acm.hdu.edu.cn/showproblem.php?pid=6113

      (2017"百度之星"程序设计大赛 - 初赛(A) - 1006)

       分步慢慢来

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    
    using namespace std;
    
    int n,m;
    char mp[111][111];
    int tag1[111][111],tag0[111][111];
    int dx[5]={0,0,1,-1};
    int dy[5]={1,-1,0,0};
    
    bool check(int x,int y)
    {
    	if(x<=0 || x>n || y<=0 || y>m)
    		return false;
    	return true;
    }
    
    void dfs1(int x,int y)
    {
    	int i,j,xx,yy;
    	tag1[x][y]=1;
    	for(i=0;i<4;i++)
    	{
    		xx=x+dx[i];
    		yy=y+dy[i];
    		if(check(xx,yy) && tag1[xx][yy]==0 && mp[xx][yy]=='1')
    			dfs1(xx,yy);
    	}
    }
    
    bool gettag1()
    {
    	int i,j;
    	for(i=1;i<=n;i++)
    		for(j=1;j<=m;j++)
    			if(mp[i][j]=='1')
    			{
    				dfs1(i,j);
    				return true;
    			}
    	return false;	
    }
    
    bool checkblock1()
    {
    	int i,j;
    	for(i=1;i<=n;i++)
    		for(j=1;j<=m;j++)
    			if(mp[i][j]=='1' && tag1[i][j]==0)
    				return false;
    	return true;
    }
    
    int dfs2(int x,int y)
    {
    	int i,j,xx,yy,ret=1;
    	tag0[x][y]=1;
    	for(i=0;i<4;i++)
    	{
    		xx=x+dx[i];
    		yy=y+dy[i];
    		if(check(xx,yy)==false)
    		{
    			ret=0;
    			continue;
    		}
    		if(tag0[xx][yy] || mp[xx][yy]=='1')
    			continue;
    		if(dfs2(xx,yy)==0)
    			ret=0;
    	}
    	return ret;
    }
    
    int getblock0()
    {
    	int ret=0,i,j;
    	for(i=1;i<=n;i++)
    		for(j=1;j<=m;j++)
    			if(mp[i][j]=='0' && tag0[i][j]==0)
    				ret+=dfs2(i,j);
    	return ret;
    }
    
    int solve()
    {
    	int i,j;
    	if(gettag1()==false)
    		return -1;
    	if(checkblock1()==false)
    		return -1;
    	int cnt=getblock0();
    	if(cnt==0)
    		return 1;
    	if(cnt==1)
    		return 0;
    	return -1;
    }
    
    void init()
    {
    	memset(tag1,0,sizeof(tag1));
    	memset(tag0,0,sizeof(tag0));
    }
    
    int main()
    {
    	int i,j;
    	while(scanf("%d%d",&n,&m)!=EOF)
    	{
    		for(i=1;i<=n;i++)
    			scanf("%s",mp[i]+1);
    		init();
    		printf("%d
    ",solve());
    	}
    	return 0;
    }
    

      

     

  • 相关阅读:
    Java Servlet(四):Servlet接口service工作(ServletRequest,ServletResponse对象)(jdk7+tomcat7+eclipse)
    Eclipse 创建文件快捷菜单、避免格式化时自动换行、.properties文件中文乱码、在线安装FreeMarker
    Java Servlet(三):Servlet中ServletConfig对象和ServletContext对象
    Java Servlet(二):servlet配置及生命周期相关(jdk7+tomcat7+eclipse)
    Java Servlet(一):创建工程(jdk7+tomcat7+eclipse)
    FlashFXP5_gr坑爹的故事
    数据库备份,及清理备份计划
    Could not load file or assembly'System.Data.SQLite.dll' or one of its depedencies
    ASP.NET MVC中,怎么使用jquery/ajaxForm上传文件
    Bootstrap modal被sliverlight掩盖。
  • 原文地址:https://www.cnblogs.com/FxxL/p/7376679.html
Copyright © 2011-2022 走看看