zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 82 (Rated for Div. 2)

    前面题看了懒得写了 直接从D开始

    D.Fill The Bag

    题解

    贪心,用(have[i]) 数组记录(2^i) 有多少个,然后对于这个(n) ,从最低位开始处理,因为每一位最多只需要1个,那么当前有的我们直接用上即可,剩下没有用上的,我们把(2^i) 合并到(2^{i+1}) 去,注意个数要除以2.如果对于当前位没有1的,那我们只能通过往后找数,拆分来获得这个数了,很显然拆离他最近的那个数最优,在拆的时候,比如我们要拆(2^j) ,目前需要(2^i) ,在过程中会产生(2^{j-1},2^{j-2},...,2^{i+1}) ,都要相应的加上。

    #include<bits/stdc++.h>
    using namespace std;
    #define mem(a,b) memset(a,b,sizeof(a))
    typedef long long LL;
    typedef pair<int,int> PII;
    #define X first
    #define Y second
    inline LL read()
    {
    	LL x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    	return x*f;
    }
    int T,m,have[70];
    LL n,t,sum;
    int main()
    {
    	T=read();
    	while(T--)
    	{
    		mem(have,0);
    		n=read();m=read();
    		LL ans=0; sum=0;
    		for(int i=1;i<=m;i++)
    		{
    			t=read();
    			sum+=t;
    			int cnt=-1;
    			while(t)cnt++,t>>=1;
    			have[cnt]++;
    		}
    		if(sum<n)
    		{
    			printf("-1
    ");
    			continue;
    		}
    		int i=0;
    		while(n)
    		{
    			if(n&1ll)
    			{ 
    				if(have[i])have[i]--;
    				else
    				{
    					for(int j=i+1;j<60;j++)
    						if(have[j])
    						{
    							have[j]--;
    							while(j>i)have[--j]++,ans++;
    							break;
    						}
    				}
    			}
    			have[i+1]+=have[i]/2;
    			n>>=1ll;i++;
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    

    Erase Subsequences

    题解

    shit为什么我写的题解全没了!!!!

    #include<bits/stdc++.h>
    using namespace std;
    #define mem(a,b) memset(a,b,sizeof(a))
    typedef long long LL;
    typedef pair<int,int> PII;
    #define X first
    #define Y second
    inline int read()
    {
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    	return x*f;
    }
    const int maxl=410;
    int T;
    char s[maxl],t[maxl];
    int dp[maxl][maxl];
    int main()
    {
    	T=read();
    	while(T--)
    	{
    		scanf("%s%s",s+1,t+1);
    		int l1=strlen(s+1),l2=strlen(t+1);
    		bool ok=0;
    		for(int k=1;k<=l2 && !ok;k++)//第一段范围1~k,第二段k+1~l2 
    		{
    			mem(dp,-1);//dp[i][j]表示s匹配到i,第一段匹配到j时候第二段的最远匹配
    			for(int i=0;i<=l1;i++)dp[i][0]=0;
    			for(int i=0;i<l1;i++)
    				for(int j=0;j<=k;j++) 
    				{
    					if(dp[i][j]==-1)continue;
    					dp[i+1][j]=max(dp[i+1][j],dp[i][j]);
    					if(s[i+1]==t[j+1])dp[i+1][j+1]=max(dp[i+1][j+1],dp[i][j]);
    					if(s[i+1]==t[dp[i][j]+1+k])dp[i+1][j]=max(dp[i+1][j],dp[i][j]+1); 
    				}
    			for(int i=0;i<=l1;i++)if(dp[i][k]==l2-k)ok=1;
    		}
    		if(!ok)printf("NO
    ");
    		else printf("YES
    ");		
    	}
    	return 0;
    }
    

    Number of Components

    题解

    这道题题目限制有一些神奇,我们可以从题目限制出手。
    首先

    #include<bits/stdc++.h>
    using namespace std;
    #define mem(a,b) memset(a,b,sizeof(a))
    typedef long long LL;
    typedef pair<int,int> PII;
    #define X first
    #define Y second
    inline int read()
    {
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    	return x*f;
    }
    const int maxn=310;
    int n,m,Q,a[maxn][maxn],f[maxn*maxn],x,y,c,all,dx[4]={0,1,0,-1},dy[4]={1,0,-1,0},ans[2000010];
    bool legal(int x,int y){return x>=0 && x<n && y>=0 && y<m;}
    vector<PII> add[2000010],del[2000010]; 
    int getf(int x){return f[x]==x ? x : f[x]=getf(f[x]);}
    bool merge(int x,int y)
    {
    	int a=getf(x),b=getf(y);
    	return a!=b ? f[a]=b,true : false;
    }
    void calc(vector<PII> &col,int t)
    {
    	for(int i=0;i<n;i++)
    		for(int j=0;j<m;j++)a[i][j]=0,f[i*m+j]=i*m+j;
    	for(auto it: col)
    	{
    		x=it.X/m,y=it.X%m;
    		a[x][y]=1;
    		int block=1;
    		for(int i=0;i<4;i++)
    		{
    			int nx=x+dx[i],ny=y+dy[i];
    			if(legal(nx,ny) && a[nx][ny]==1)
    				block-=merge(x*m+y,nx*m+ny);
    		}
    		if(it.Y==Q+1)ans[it.Y]+=t*block;
    	}
    }
    int main()
    {
    	n=read();m=read();Q=read();
    	for(int i=1;i<=Q;i++)
    	{
    		x=read()-1;y=read()-1;c=read();
    		int pos=x*m+y;
    		if(i==Q)all=c; 
    		add[c].push_back(make_pair(pos,i));
    		del[a[x][y]].push_back(make_pair(pos,i));
    		a[x][y]=c;
    	}
    	for(int i=0;i<n;i++)
    		for(int j=0;j<m;j++)
    			del[a[i][j]].push_back(make_pair(i*m+j,Q+1));
    	for(int i=0;i<=all;i++)reverse(del[i].begin(),del[i].end()); 
    	for(int i=1;i<=all;i++)calc(add[i],1);
    	for(int i=0;i<=all;i++)calc(del[i],-1);
    	for(int i=1,tmp=1;i<=Q;i++)tmp+=ans[i],printf("%d
    ",tmp);
    	return 0;
    }
    

    废话

    做2600以上太困难了...

  • 相关阅读:
    贪心:字典树openjudge1799-最短前缀
    BFS:noi6044鸣人与佐助
    广搜:codevs-3344(初步bfs)
    2016noip感想(普及组)
    NOI-Openjudge-8462-大盗阿福
    20155326 第12周课堂实践总结(二)String类和Arrays类的学习
    20155326 第12周课堂实践总结(一)
    20155326 实验三 敏捷开发与XP实践
    20155326 2016-2017-2 《Java程序设计》第十周学习总结
    2016-2017-2 20155326实验二《Java面向对象程序设计》实验报告
  • 原文地址:https://www.cnblogs.com/FYH-SSGSS/p/12329347.html
Copyright © 2011-2022 走看看