zoukankan      html  css  js  c++  java
  • codeforces round 417 div2 补题 CF 812 A-E

    Sagheer and Crossroads

    水题略过(然而被Hack了 以后要更加谨慎)

    #include<bits/stdc++.h>
    using namespace std;
    
    
    
    
    
    int main()
    {
     //freopen("t.txt","r",stdin);
     int a[4][4];
     //memset(a,0,sizeof(a));
     for(int i=0;i<4;i++)
     	for(int j=0;j<4;j++)
     		scanf("%d",&a[i][j]);
     bool flag=false;
     for(int i=0;i<4;i++)
     	{
     	 if(!a[i][3])continue;
     	 if(a[i][0]||a[i][1]||a[i][2]||a[(i+1)%4][0]||a[(i+2)%4][1]||a[(i+3)%4][2]){flag=true;break;}
    	}
     if(flag)printf("YES
    ");
     	else printf("NO
    ");
     return 0;
    }
    

    B Sagheer, the Hausmeister

    很简单的DP 由于不关掉本层的灯不能上楼,问题就好办了。

    dp[i][0]表示从顶层到第i层全关完且从左边出发的minicost dp[i][1]表示从右边出发的

    转移方程是显而易见的

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long int LL;
    
    
    int bulb[16][110],le[16],ri[16];
    LL dp[16][2];
    int main()
    {
     //freopen("t.txt","r",stdin);
     int n,m;
     scanf("%d%d",&n,&m);
     for(int i=0;i<n;i++)
     	{
     	 le[i]=ri[i]=-1;
     	 getchar();
     	 for(int j=0;j<m+2;j++)
     	 	{
     	 	 char c=getchar();
     	 	 if(c=='0')bulb[i][j]=0;
     	 	 	else bulb[i][j]=1;
     	 	 //scanf("%d",&bulb[i][j]);
     	 	 if(!bulb[i][j])continue;
     	 	 if(le[i]==-1)le[i]=j;
     	 	 	else le[i]=min(le[i],j);
     	 	 if(ri[i]==-1)ri[i]=j;
     	 	 	else ri[i]=max(ri[i],j);
    		}
    	}
     dp[0][0]=max(0,ri[0]);
     if(le[0]==-1)dp[0][1]=0;
     	else dp[0][1]=(m+2)-le[0]-1;
     for(int i=1;i<n;i++)
     	{
     	 	if(dp[i-1][0]==0&&dp[i-1][1]==0)
    		  dp[i][0]=max(0,ri[i]);
    		 else  dp[i][0]=max(0,ri[i])+min(max(0,ri[i])+1+dp[i-1][0],m+2-max(0,ri[i])+dp[i-1][1]);
     	 	
     	 int lx;
     	 if(le[i]==-1)lx=0;
     	 	else lx=(m+2)-le[i]-1;
     	 if(dp[i-1][0]==0&&dp[i-1][1]==0)
     	  dp[i][1]=lx;
     	  else
     	 dp[i][1]= lx+min(m+2-lx+dp[i-1][0],lx+1+dp[i-1][1]);
    	}
     printf("%I64d
    ",dp[n-1][0]);
     return 0;
    }
    

    Sagheer and Nubian Market

    二分答案判断是否可行即可。复杂度O(nlognlogn)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long int LL;
    
    LL mid;
     LL n,s;
    struct suv
    {
     LL v;
     LL x;
    };
    vector<suv>num;
    bool cmp(suv a,suv b)
    {
     return a.v+a.x*mid<b.v+b.x*mid;
    }
    LL doa()
    {
     sort(num.begin(),num.end(),cmp);
     LL sum=0;
     for(int i=0;i<mid;i++)
     	{
     	 sum+=num[i].v+num[i].x*mid;
    	}
     if(sum>s)return -1;
     	else return sum;
    }
    
    int main()
    {
     //freopen("t.txt","r",stdin);
     num.clear();
    
     scanf("%I64d%I64d",&n,&s);
     num.resize(n);
     LL min=1e+15;
     int minj=-1;
     for(int i=0;i<n;i++)
     {
      scanf("%I64d",&num[i].v);
      num[i].x=i+1;
     }
     LL l=0,r=n;
     LL sm;
     LL bestm=0,bestk=0;
     while(l<=r)
     	{
     	 mid=(l+r)>>1;
     	 sm=doa();
     	 if(sm==-1)r=mid-1;
     	 	else l=mid+1,bestm=mid,bestk=sm;
    	}
     printf("%I64d %I64d
    ",bestm,bestk);
     return 0;
    }
    

    Sagheer and Kindergarten

     这道题 可以说又臭又长。。不知道是不是埃及洋文好的人不多。

     总结一下题意: 给定一个特殊的DAG 怎么特殊呢? 不会存在一个点指向多个点。

     每次询问添加一条边,询问有多少个点进入了特殊集合 满足这个集合中所有点都有指向的点,且他们指向的点也均在这个集合中。

    反向dfs一下就可以了。。

    #include <bits/stdc++.h>
    using namespace std;
    #define ll int
    #define N ((ll)101*1000)
    
    ll n,m,k,q,a[N],b[N],lst[N],strt[N],fnsh[N],sz[N],now;
    vector <ll> e[N];
    bool dad[N];
    
    void dfs(ll x)
    {  
    	sz[x]=1,strt[x]=now++;
    	for(auto u:e[x])
    		dfs(u),sz[x]+=sz[u];
    	fnsh[x]=now;
    }
    
    int main()
    {
    	ios_base::sync_with_stdio(0);cin.tie(0);
    	cin>>n>>m>>k>>q;
    	for(int i=0;i<k;i++)
    	{
    		ll x,y;
    		cin>>x>>y;
    		if(lst[y])e[lst[y]].push_back(x),dad[x]=1;
    		lst[y]=x;
    	}
    	for(int i=1;i<=n;i++)
    		if(!dad[i])
    			dfs(i);
    	while(q--)
    	{
    		ll x,y;
    		cin>>x>>y;
    		if(!lst[y]){cout<<"0
    ";continue;}
    		if(strt[x]<strt[lst[y]] && strt[lst[y]]<fnsh[x])cout<<sz[x]<<"
    ";
    		else cout<<"0
    ";
    	}
    	return 0;
    }
    

      

    Sagheer and Apple Tree

     很有趣的一道Nim游戏题

      题目给的树的性质该怎么利用呢?

      所有叶子节点到根节点的距离要么都是偶数要么都是奇数。

      我们是不是可以考虑把所有节点分成两种类型,一种是到根节点的距离的奇偶性与叶节点相同(集合P),一种不同(集合Q)。

      如果对手移动P中节点p,如果P中还有一个节点的苹果数量和p相同,我就可以模仿对手。

      如果对手移动Q中节点,我也可以模仿(吃掉或者继续往下走)。

      所以需要考虑的就是P中节点的异或值x。如果为0,最初就是必胜态。

      不为0该怎么办呢? 考虑在Q中找一个恰当的节点替换当前节点。

      需要的苹果数为A【i】^x 为什么呢?(学好近世代数很重要)

      看代码吧 很简单。

      

    #include<bits/stdc++.h>
    using namespace std;
    struct node
    {
    	int y,next;
    }a[100010];
    int first[100010],len;
    int A[100010];
    int d[100010],t;
    int s[21000000];
    void ins(int x,int y)
    {
    	a[++len].y=y;
    	a[len].next=first[x];
    	first[x]=len;
    }
    void dfs(int x,int fa)
    {
    	int k,y,ok=1;
    	d[x]=d[fa]^1;
    	for(k=first[x];k;k=a[k].next)
    	{
    	  y=a[k].y;
    	  ok=0;
    	  dfs(y,x);
    	}
    	if(ok)t=d[x];//判断奇偶 
    }
    int main()
    {
    	int n,i,j,x,sum=0;
    	long long ans=0;
    	scanf("%d",&n);
    	for(i=1;i<=n;i++)
    	  scanf("%d",&A[i]);
    	for(i=2;i<=n;i++)
    	{
    	  scanf("%d",&x);
    	  ins(x,i);
    	}
    	dfs(1,0);
    	x=0;
    	for(i=1;i<=n;i++)
    	  if(d[i]==t)x^=A[i],sum++;
    	  else s[A[i]]++;
    	if(!x)ans+=(long long)sum*(sum-1)/2+(long long)(n-sum)*(n-sum-1)/2;//最初就是必胜态 
    	for(i=1;i<=n;i++)
    	  if(d[i]==t)ans+=s[A[i]^x];
    	printf("%I64d
    ",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    moment.js获取当前日期是当年的第几周
    angulajs中引用chart.js做报表,修改线条样式
    moment算本月开始日期和结束日期
    TFS(Team Foundation Server)敏捷使用教程(四):工作项跟踪(1)
    个人微信收款回调通知
    Winform,Wpf快捷键
    RemindMe
    数组循环左移p位
    RemindMe 说明
    双网卡同时上内外网
  • 原文地址:https://www.cnblogs.com/heisenberg-/p/6931439.html
Copyright © 2011-2022 走看看