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

    反思

    • 暴力一定要打,T2 (O(n^6))有70分,加上二维前缀和就将近(A)掉了,可能有时候并不知道最优解,但是一定要把能拿到的分拿到

    简述

    T1

    一道dp,设(f[i][j])(s1,s2)分别到(i.j)位时最小距离,状态转移方程易得:

    [f[i][j]=min(f[i-1][j]+k,f[i][j-1]+k,f[i-1][j-1]+dif(i,j)) ]

    T2

    解锁了二维哈希新姿势
    会的话就是板子了……

    
    
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define ZZ_zuozhe int main()
    #define N 105
    
    ull n;
    ull a[N][N],b[N][N];
    const ull base1=11,base2=13;
    ull p1[N],p2[N];
    void pp()
    {
    	p1[0]=p2[0]=1;
    	for(int i=1;i<=n;i++)p1[i]=p1[i-1]*base1;
    	for(int i=1;i<=n;i++)p2[i]=p2[i-1]*base2;
    }
    
    ull get(ull aa[][N],ll x,ll y,ll h)
    {
    	return aa[x][y]-aa[x-h][y]*p2[h]-aa[x][y-h]*p1[h]+aa[x-h][y-h]*p1[h]*p2[h];
    }
    
    map<ull,bool>mp;
    
    ZZ_zuozhe
    {
    	scanf("%lld",&n);
    	pp();
    	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%lld",&a[i][j]);
    	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%lld",&b[i][j]);
    	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)a[i][j]=a[i][j-1]*base1+a[i][j];
    	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)a[i][j]=a[i-1][j]*base2+a[i][j];
    	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)b[i][j]=b[i][j-1]*base1+b[i][j];
    	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)b[i][j]=b[i-1][j]*base2+b[i][j];
    	for(int k=0;k<=n;k++)for(int i=k;i<=n;i++)for(int j=k;j<=n;j++)mp[get(a,i,j,k)]=1;
    	for(int k=n;k>=0;k--)for(int i=k;i<=n;i++)for(int j=k;j<=n;j++)if(mp.find(get(b,i,j,k))!=mp.end()){printf("%d",k);return 0;}
    	return 0;
    }
    

    刚开始想的是二维前缀和,然后转到二维哈希发现并不会写……
    其实二维前缀和+暴力比较似乎直接能(A)掉?所以以后暴力分一定要打……

    T3

    一个结论:对于一个数,把他分解质因数,得到(A=p_1^{a_1}cdot p_2^{a_2}cdot dots cdot p_n^{a_n})
    则这个数约数总数为((a_1+1)cdot (a_2+1)cdot dots cdot (a_n+1))
    所以可以用一个dfs搜索答案
    注意:如果质因数指数和相同的情况下,为了使他更小,应当尽量使用更小的质因数,可以发现质因数的指数应该是单调不增的。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    ll n,ans=-1,maxn=-1;
    
    const ll p[20]={1,2,3,5,7,11,13,17,19,23,29,31};
    
    void dfs(ll now,ll cnt,ll t,ll po)
    {
    	if(t>maxn||(t==maxn&&now<ans))
    	{
    		ans=now;
    		maxn=t;
    	}
    	ll tmp=now;
    	for(int i=1;i<=po;i++)
    	{
    		if(tmp*p[cnt]>n)break;
    		tmp*=p[cnt];
    		if(tmp<=n)dfs(tmp,cnt+1,t*(i+1),i);
    	}
    }
    
    int main()
    {
    	scanf("%lld",&n);
    	dfs(1,1,1,30);
    	printf("%lld",ans);
    	return 0;
    }
    

    T4

    一道贪心好题
    需要注意的是看出贪心的过程:如果当前必须把一个玩具放上去,如果这个玩具马上就要用了,还要把它拿下来,再把另外一个放上去……会造成很多不必要的麻烦
    所以,每次需要把玩具放上去时,应当找一个再拿下来时间最晚的玩具放上去,尽量减少其对其他玩具的影响。
    这里用到了(priority_queue)(pair)(STL)我一直都不很熟……以后得多看看,因为有时候它是真的方便……

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long 
    #define ull unsigned long long
    #define ZZ_zuozhe int main()
    #define N 500005
    
    ll n,k,p,now,ans=0;
    ll a[N],last[N],next[N];
    bool vis[N];
    priority_queue<pair<ll,ll> > Q;
    pair<ll,ll> pt;
    
    int main()
    {
    	scanf("%lld%lld%lld",&n,&k,&p);
    	for(int i=1;i<=p;i++)scanf("%lld",&a[i]);
    	for(int i=1;i<=p;i++)last[a[i]]=p+1;
    	for(int i=p;i>=1;i--)next[i]=last[a[i]],last[a[i]]=i;
    	
    	for(int i=1;i<=p;i++)
    	{
    		if(vis[a[i]])
    		{
    			k++;
    			Q.push(make_pair(next[i],a[i]));
    		}
    		else 
    		{
    			if(!Q.empty()&&Q.size()==k)
    			{
    				pt=Q.top();
    				Q.pop();
    				vis[pt.second]=0;
    			}
    			ans++;
    			Q.push(make_pair(next[i],a[i]));
    			vis[a[i]]=1;
    		}
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    Git常用命令
    C++ 四种强制类型转换
    Linux系统日志及日志分析
    C/C++中的getline函数总结:
    标准C++中的string类的用法总结
    C++中map的基本操作和使用;
    一个C++类的注释:
    C++ 中宏的使用 --来自:http://blog.csdn.net/hgl868/article/details/7058906
    c++ 的vector
    c++强制类型转换:dynamic_cast、const_cast 、static_cast、reinterpret_cast
  • 原文地址:https://www.cnblogs.com/zzzuozhe-gjy/p/13413172.html
Copyright © 2011-2022 走看看