22.4.24

1,Fedor and New Game;2,谜一样的牛+pbds初学+vector模拟平衡树;3,剪枝;


1,Fedor and New Game

lowbit 操作取最低位1;

找各个位置上的数,相同位置,数字不同的最多限制个数为k个;

#include<bits/stdc++.h>
#define rep1(i,a,n) for(register ll i=a;i<n;i++) 
#define rep2(i,a,n) for(register ll i=a;i<=n;i++) 
#define per1(i,n,a) for(register ll i=n;i>a;i--) 
#define per2(i,n,a) for(register ll i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define INF 0x3f3f3f3f
#define pb push_back
#define endl "\n"
#define xiaoshu(a) setprecision(a)
#define lowbit(x) (-x&x)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
const int N=1e4+10;
int n,m,k;
int x[N];
bool isfriend(int x,int y)
{
	int cs=0;
	while(x!=0||y!=0)
	{
		if(x%2!=y%2)cs++;
		x>>=1;
		y>>=1;
		if(cs>k)return 0;
	}
	return 1;
}	
signed main()
{
	quick_cin();
	cin>>n>>m>>k;
	rep2(i,1,m)cin>>x[i];
	int x1;cin>>x1;
	int ans=0;
	rep2(i,1,m)
	{
		if(isfriend(x[i],x1))
		{
			ans++;
		}
	}
	cout<<ans;
	return 0;
}

 2,谜一样的牛;

题意:

一共1~n个身高的n头牛,n头牛站成一排,给出n-1行数,表示第i头的前边有多少头比他高的牛;

解法:从后往前找,该头牛的身高,为队伍里剩下的牛的第rank+1头牛 ;

rank:0,从1 2 3 4 5中,第0+1小的牛,即身高为1的牛;

rank:1,从2 3 4 5中,第1+1头小的牛,即身高为3的牛;

。。。

最终能找完;

两步操作:1,从队伍里找到第k小的数;2,从队伍里删除一个数;

所以平衡树很容易解决,虽然有点杀鸡焉用牛刀的感觉,但是vector写刚好快些;

第一时间想到了vector来做,正好熟悉下vector 的操作;

a.reserve(N)给a向量预先分配容量为N;vector容量和size是两码事!

扩容量是个耗费时间的过程,所以不如预先设置好容量!;

  1. 插入数值 xx。
  2. 删除数值 xx(若有多个相同的数,应只删除一个)。
  3. 查询数值 xx 的排名(若有多个相同的数,应输出最小的排名)。
  4. 查询排名为 xx 的数值。
  5. 求数值 xx 的前驱(前驱定义为小于 xx 的最大的数)。
  6. 求数值 xx 的后继(后继定义为大于 xx 的最小的数)。

case 1:a.insert(upper_bound(a.begin(),a.end(),x),x); break;

case 2:a.erase(lower_bound(a.begin(),a.end(),x)); break;

case 3:cout<<lower_bound(a.begin(),a.end(),x)-a.begin()+1<<endl; break;

case 4:cout<<a[x-1]<<endl; break;

case 5:cout<<(*--lower_bound(a.begin(),a.end(),x))<<endl; break;

case 6:cout<<(*upper_bound(a.begin(),a.end(),x))<<endl; break; 

#include<bits/stdc++.h>
#define rep1(i,a,n) for(register ll i=a;i<n;i++) 
#define rep2(i,a,n) for(register ll i=a;i<=n;i++) 
#define per1(i,n,a) for(register ll i=n;i>a;i--) 
#define per2(i,n,a) for(register ll i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define INF 0x3f3f3f3f
#define pb push_back
#define endl "\n"
#define xiaoshu(a) setprecision(a)
#define lowbit(x) (-x&x)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
const int N=1e6+10;
vector<int>niu;
vector<int>ans;
signed main()
{
	quick_cin();
	cin>>n;
	niu.reserve(N);
	ans.reserve(N);
	niu.pb(1);
	rep2(i,2,n)
	{
		cin>>b[i];
		niu.pb(i);
	}
	per2(i,n,1)
	{
		if(i>1)
		{
			ans.pb(niu[b[i]]);
			niu.erase(lower_bound(niu.begin(),niu.end(),niu[b[i]]));
		}
		else ans.pb(niu[0]);
	}
	per2(i,ans.size()-1,0)cout<<ans[i]<<endl;
	return 0;
}

pbds库的平衡树:

dev不能用#include<bits/extc++.h>;

需要把用到的打出来,也就4种东西,平衡树,哈希表,trie树和优先队列;

也是从0开始的,所以输出第x个数就是*tr.find_by_order(x-1);

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#include<ext/pb_ds/trie_policy.hpp>
#include<ext/pb_ds/priority_queue.hpp>
#define rep1(i,a,n) for(register ll i=a;i<n;i++) 
#define rep2(i,a,n) for(register ll i=a;i<=n;i++) 
#define per1(i,n,a) for(register ll i=n;i>a;i--) 
#define per2(i,n,a) for(register ll i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define endl "\n"
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
int n;
using treap=tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;
treap tr;
const int N=1e5+10;
int pm[N];
int as[N],k;
signed main()
{
	quick_cin();
	cin>>n;
	tr.insert(1);
	rep2(i,2,n)tr.insert(i),cin>>pm[i];
	per2(i,n,1)
	{
		if(i!=1)
		{
			int ans=*tr.find_by_order(pm[i]);
			as[k++]=ans;
			tr.erase(tr.lower_bound(ans));
		}
		else
		{
			as[k++]=*tr.find_by_order(0);
		}
	}
	per2(i,k-1,0)cout<<as[i]<<endl;
	return 0;
}

竟然和用vector模拟的平衡树时间差不多,。。,也没快多少貌似。。 ;还是手写的牛啊;

还有就是谜一样的牛

使用复杂的pbds操作,没想到和vecto模拟的平衡树不相上下,甚至有时还慢,被坑了感觉。。而且pbds的树无法插入相同元素,反而vector可以;

 所以要不要用pbds?平衡树已经可以用上面的vector来模拟了,并且写法更简洁,需要的头文件和相关操作也少,所以还是作为了解吧!

3,剪枝;

泉水:
题意:一共n个桶(n为偶数),对应n/2个挑水时间,每次可以取i,j两个桶,消耗t[i][j]时间,

打满所有的桶所需的最短时间;

主要是枚举状态,因为本质上还是在1~n种选,只不过一次要拿两个,所以枚举的状态有些变化;

另外就是剪枝了;

#include<bits/stdc++.h>
//#include<ext/pb_ds/assoc_container.hpp>
#define rep1(i,a,n) for(register ll i=a;i<n;i++) 
#define rep2(i,a,n) for(register ll i=a;i<=n;i++) 
#define per1(i,n,a) for(register ll i=n;i>a;i--) 
#define per2(i,n,a) for(register ll i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define endl "\n"
#define lowbit(x) (-x&x)
using namespace std;
//using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
int t[100][100];
bool hs[100];
int n;
int ans=INT_MAX;
void dfs(int x,int sum)
{
	if(x>n)
	{
		ans=min(ans,sum);
		return;
	}
	if(sum>=ans)return;
	if(!hs[x])
	{
		hs[x]=1;
		rep2(i,1,n)
		{
			if(!hs[i])
			{
				hs[i]=1;
				dfs(x+1,sum+t[x][i]);
				hs[i]=0;
			}
		}
		hs[x]=0;
	}
	else dfs(x+1,sum);
}
signed main()
{
    quick_cin();
	cin>>n;
	rep2(i,1,n)
	 rep2(j,1,n)cin>>t[i][j];
	dfs(1,0);
	cout<<ans;
    return 0;
}

最佳调度问题;

if(sum>ans)return;是错误的,会tle,>=都return;有了最小值就return 就i好;

#include<bits/stdc++.h>
//#include<ext/pb_ds/assoc_container.hpp>
#define rep1(i,a,n) for(register ll i=a;i<n;i++) 
#define rep2(i,a,n) for(register ll i=a;i<=n;i++) 
#define per1(i,n,a) for(register ll i=n;i>a;i--) 
#define per2(i,n,a) for(register ll i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define endl "\n"
#define lowbit(x) (-x&x)
using namespace std;
//using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
const int N=1e5+10;
int n,k;
int t[N];
int rob[N];
int ans=INT_MAX;
void dfs(int x,int sum)
{
    if(x>n)
    {
        if(ans>sum)ans=sum;
        return ;
    }
    if(sum>=ans)return;
    rep2(i,1,k)
    {
        if(rob[i]+t[x]<ans)
        {
            rob[i]+=t[x];
            dfs(x+1,max(sum,rob[i]));
            rob[i]-=t[x];
        }
    }
}
signed main()
{
    quick_cin();
    cin>>n>>k;
    rep2(i,1,n)cin>>t[i];
    sort(t+1,t+n+1,greater<int>());
    dfs(1,0);
    cout<<ans;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dull丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值