zoukankan      html  css  js  c++  java
  • 「考试」大假期集训模拟16

    反思

    • 第二遍了,一定要看数据范围……

    题目简述

    T1 老光棍

    可以(hash)一波带走,复杂度是(O(Tn))
    注意:多解的情况是“不同的字符串(A)”,所以在增加答案的时候需要特别判断其和原来的答案是否相同
    code:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define N 2000005
    
    ll T,n;
    char s[N];
    bool vis[30],flag;
    ll ans=0,pos;
    
    const ull base=31;
    ull hash[N],po[N];
    void pp()
    {
    	po[0]=1;
    	for(int i=1;i<=N;i++)po[i]=po[i-1]*base;
    }
    void gethash()
    {
    	memset(hash,0,sizeof hash);
    	hash[0]=0;
    	for(int i=1;i<=n;i++)
    	{
    		hash[i]=hash[i-1]*base+(s[i]-'A');
    	}
    }
    ull get(ll l,ll r)
    {
    	if(l>r)return 0;
    	return hash[r]-hash[l-1]*po[r-l+1];
    }
    ull tmp;
    
    int main()
    {
    	//freopen("owo.in","r",stdin);
    	scanf("%lld",&T);
    	pp();
    	while(T--)
    	{
    		scanf("%lld",&n);
    		scanf("%s",s+1);
    		if(n%2==0)
    		{
    			puts("NOT POSSIBLE");
    			continue;
    		}
    		gethash();
    		ll t=(n+1)/2;
    		ans=0;
    		tmp=-1;
    		//cout<<endl;
    		for(int i=1;i<=t;i++)
    		{
    			//cout<<1<<' '<<i-1<<' '<<i+1<<' '<<t<<' '<<t+1<<' '<<t+i-1<<' '<<t+i<<' '<<n<<endl;
    			//cout<<get(1,i-1)<<' '<<get(t+1,t+i-1)<<' '<<get(i+1,t)<<' '<<get(t+i,n)<<endl;
    			if(get(1,i-1)==get(t+1,t+i-1)&&get(i+1,t)==get(t+i,n))
    			{	
    				if(get(t+1,n)!=tmp)ans++;
    				tmp=get(t+1,n);
    				pos=i;
    				//cout<<pos<<endl;
    			}
    		}
    		for(int i=t+1;i<=n;i++)
    		{
    			//cout<<get(1,i-t)<<' '<<get(t,i-1)<<' '<<get(i-t+1,t-1)<<' '<<get(i+1,n)<<endl;
    			if(get(1,i-t)==get(t,i-1)&&get(i-t+1,t-1)==get(i+1,n))
    			{
    				if(get(1,t-1)!=tmp)ans++;
    				tmp=get(1,t-1);
    				pos=i;
    				//cout<<pos<<endl;
    			}
    		}
    		if(ans>1)
    		{
    			puts("NOT UNIQUE");
    		}
    		else if(ans==0)
    		{
    			puts("NOT POSSIBLE");
    		}
    		else 
    		{
    			if(pos<=t)
    			{
    				for(int i=t+1;i<=n;i++)putchar(s[i]);
    			}
    			else
    			{
    				for(int i=1;i<=t-1;i++)putchar(s[i]);
    			}
    			puts("");
    		}
    	}
    	return 0;
    }
    

    T2 渔船

    网络流?三分?在补了在补了……
    (然而还并不知道网络流为何物
    (可能不久会放上来……

    T3 马克的达人秀

    原题luoguP4377 Talent Show
    01分数规划:洛谷日报(#121)
    01分数规划+01背包( ightarrow)最优比率背包
    code:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define N 255
    #define T 250005
    
    ll n,ww;
    ll t[N],w[N];
    ll sum=0;
    ll f[T];
    
    bool work(ll x)
    {
    	memset(f,128,sizeof f);
    	f[0]=0;
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=ww;j>=0;j--)
    		{
    			f[min(j+w[i],ww)]=max(f[min(j+w[i],ww)],f[j]+t[i]-x*w[i]);
    		}
    	}
    	return f[ww]>=0;
    }
    
    int main()
    {
    	//freopen("owo.in","r",stdin);
    	//freopen("awa.out","w",stdout);
    	scanf("%lld%lld",&n,&ww);
    	for(int i=1;i<=n;i++)scanf("%lld%lld",&w[i],&t[i]),t[i]*=1000;
    	ll l=0,r=10000000,m;
    	while(l<r)
    	{
    		m=(l+r)>>1;
    		//cout<<m<<endl;
    		if(work(m))l=m+1;
    		else r=m;
    	}
    	printf("%lld",l-1);
    	return 0;
    }
    

    T4 爬山

    一个比较有用的结论:

    给定一组数据,用猜来的平均值计算他的方差,计算结果一定(geq)正确结果

    推柿子:(by yspm
    (设数据(x_1dots x_n)已经给定,猜的平均数为(ar{x}),为了方便,所有的(sumlimits^{n}_{i=1})简写为(sum)

    [egin{aligned} s^2&=frac{sum(x_i-ar{x})^2}{n}\ &=frac{sum(x_i^2)-2sum(x_iar{x})+sum(ar{x}^2)}{n}\ frac{sum(x_i^2)}{n}是定值,去掉\ &=frac{sum(ar{x}^2)-2sum(x_iar{x})}{n}\ &=ar{x}^2-frac{2sum(x_iar{x})}{n}\ &=ar{x}^2-frac{2ar{x}sum x_i}{n}\ 配方得\ &=(ar{x}-frac{sum x_i}{n})^2-(frac{sum x_i}{n})^2\ 当且仅当取ar{x}=frac{sum x_i}{n}时,取最小值\ 其中frac{sum x_i}{n}即为正确的平均数\ end{aligned}]

    所以,可以枚举每个点到终点的路径长度与经过的点数,从而得到这条路径的平均值,用这个“猜到”的平均值计算到终点的最小方差,取所有这些答案里的最小值就是正确答案
    另外有向无环图可以用拓扑排序帮助求最短路
    code:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define db double
    #define E 2005
    #define N 55
    #define inf 10000000000000000
    
    struct edge
    {
    	ll u,v,w;
    }e[E];
    ll head[E],next[E],tot=0;
    void add(ll a,ll b,ll c)
    {
    	++tot;
    	e[tot].u=a;
    	e[tot].v=b;
    	e[tot].w=c;
    	next[tot]=head[a];
    	head[a]=tot;
    }
    
    ll n,m,a,b,c;
    ll in[N],tmp[N];
    double ans=1e16;
    queue<ll> q;
    ll mi[N][25],mx[N][25];
    db dis[N][25];
    
    int main()
    {
    	//freopen("owo.in","r",stdin);
    	scanf("%lld%lld",&n,&m);
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%lld%lld%lld",&a,&b,&c);
    		add(a,b,c);
    		in[b]++;
    	}
    	while(!q.empty())q.pop();
    	memcpy(tmp,in,sizeof in);
    	for(int i=1;i<=n;i++)if(!tmp[i])q.push(i);
    	for(int i=1;i<=n;i++)for(int j=0;j<=20;j++)mi[i][j]=inf,mx[i][j]=-inf;
    	mi[1][0]=mx[1][0]=0;
    	while(!q.empty())
    	{
    		ll u=q.front();
    		//cout<<u<<endl;
    		q.pop();
    		for(int i=head[u];i;i=next[i])
    		{
    			ll v=e[i].v;
    			for(int j=0;j<=19;j++)
    			{
    				if(mi[u][j]!=inf)
    				{
    					mi[v][j+1]=min(mi[v][j+1],mi[u][j]+e[i].w);
    					mx[v][j+1]=max(mx[v][j+1],mx[u][j]+e[i].w);
    					//cout<<mi[v][j+1]<<' '<<mx[v][j+1]<<endl;
    				}
    			}
    		}
    		for(int i=head[u];i;i=next[i])
    		{
    			ll v=e[i].v;
    			if(--tmp[v]==0)q.push(v);
    		}
    	}
    	for(int i=1;i<=19;i++)
    	{
    		//cout<<mi[n][i]<<endl;
    		if(mi[n][i]==inf)continue;
    		for(int j=mi[n][i];j<=mx[n][i];j++)
    		{
    			db avg=(db)j/(db)i;
    			//cout<<avg<<endl;
    			memcpy(tmp,in,sizeof in);
    			for(int k=1;k<=n;k++)for(int l=0;l<=19;l++)dis[k][l]=inf;
    			dis[1][0]=0;
    			while(!q.empty())q.pop();
    			for(int k=1;k<=n;k++)if(!tmp[k])q.push(k);
    			while(!q.empty())
    			{
    				ll u=q.front();
    				q.pop();
    				//cout<<u<<endl;
    				for(int k=0;k<i;k++)
    				{
    					if(dis[u][k]==inf)continue;
    					for(int l=head[u];l;l=next[l])
    					{
    						ll v=e[l].v,w=e[l].w;
    						dis[v][k+1]=min(dis[v][k+1],dis[u][k]+((db)w-avg)*((db)w-avg));
    					}
    				}
    				for(int k=head[u];k;k=next[k])
    				{
    					ll v=e[k].v;
    					if(--tmp[v]==0)q.push(v);
    				}
    			}
    			//cout<<dis[n][i]<<endl;
    			ans=min(ans,dis[n][i]/(db)i);
    		}
    	}
    	printf("%.4lf",ans);
    	return 0;
    }
    
  • 相关阅读:
    2031 HDOJ 进制转换
    计算机视觉实验之直方图均衡化和对数变换
    sublime text3创建文件时生成头部注释
    浏览器调试出错
    css世界-读书笔记
    redis中Bitmaps位图应用场景
    redis中hyperloglog基数统计
    redis中Zset有序集合类型常用命令
    redis中set集合类型常用命令
    redis中hash哈希类型常用命令
  • 原文地址:https://www.cnblogs.com/zzzuozhe-gjy/p/13449178.html
Copyright © 2011-2022 走看看