9.21洛谷刷题

P5076 【深基16.例7】普通二叉树(简化版)

        维护一个单调序列,要用set。常用的set操作如下:

#include<bits/stdc++.h>
using namespace std;

multiset<int> S;

int main(void)
{
	int n;cin>>n;
	for(int i=0;i<n;i++){
		int op,num;
		cin>>op>>num;
		if(op==5)
			S.insert(num);
		else if(op==3){
			auto it=S.lower_bound(num);
			if(it!=S.begin()) cout<<*(--it)<<endl;
			else cout<<"-2147483647"<<endl;
		}else if(op==4){
			auto it=S.upper_bound(num);
			if(it!=S.end()) cout<<*it<<endl;
			else cout<<"2147483647"<<endl;
		}else if(op==2){
			auto it=S.begin();
			int cnt=num-1;
			while(cnt--) it++;
			cout<<*it<<endl;
		}
		else{
			auto it=S.lower_bound(num);
			int rank=1;
			while(it!=S.begin()){
				it--;
				rank++;
			}
			cout<<rank<<endl;
		}
	}
}

P1433 吃奶酪

状态压缩DP,经典哈密顿路径

#include<bits/stdc++.h>
using namespace std;

vector<pair<double,double> > V;
double dp[1<<16][21];
double dist[21][21];

double fun(int a,int b)
{
	int x=V[a].first,y=V[a].second;
	int u=V[b].first,v=V[b].second;
	return sqrt((x-u)*(x-u)+(y-v)*(y-v));
}
int main(void)
{
	memset(dp,0x7f,sizeof(dp));
	int n;cin>>n;
	V.push_back({0,0});
	for(int i=0;i<n;i++){
		double x,y;cin>>x>>y;
		V.push_back({x,y});
	}

	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			if(i!=j)
				dist[i][j]=fun(i,j);

	n++;
	dp[1][0]=0;
	for(int S=1;S<(1<<n);S++)
		for(int j=0;j<n;j++)
			if((S>>j)&1)
				for(int k=0;k<n;k++)
					if((S^(1<<j)) >> k & 1)
						dp[S][j]=min(dp[S^(1<<j)][k]+dist[k][j],dp[S][j]);
	
	double Min=0x7f7f7f7f;
	for(int j=1;j<=n;j++)
		Min=min(Min,dp[(1<<n)-1][j]);


	printf("%.2lf",Min);
}

P1032 [NOIP2002 提高组] 字串变换

BFS

#include<bits/stdc++.h>
using namespace std;

string a,b;
vector<pair<string,string> > V;

map<string,bool> flag;
int Min=0;

//void dfs(string x,string y,int step)
//{
//	if(step>10) return ;
//	if(step>=Min) return ;
//	if(x==y){
//		Min=min(Min,step); 
//		return ;
//	}
//	
//
//	for(int i=0;i<V.size();i++){
//		auto it=V[i];
//		string u=it.first,v=it.second;
//		string ans;
//		int idx=0;
//		while((idx=x.find(u,idx)) != -1){
//			if(idx==-1) break;
//			ans=x;
//			ans.replace(idx,u.length(),v);
//			if(flag[ans]) continue;
//			flag[ans]=true;
//			dfs(ans,y,step+1);
//			flag[ans]=false;
//			idx+=u.length();
//		}	
//	}
//}

int bfs()
{
	queue<string> Q;
	Q.push(a);
	flag[a]=true;
	int Min=0;
	while(Q.size()){
		int cnt=Q.size();
		Min++;
		if(Min>10) return Min;
		while(cnt--){
			string x=Q.front();
//			cout<<x<<endl;
			Q.pop();
			if(x==b) return Min;
			for(int i=0;i<V.size();i++){
				auto it=V[i];
				string u=it.first,v=it.second;
				string ans;
				int idx=0;
				while((idx=x.find(u,idx)) != -1){
					if(idx==-1) break;
//					cout<<ans<<" "<<x<<" "<<i<<" "<<idx<<endl;
					ans=x;
					ans.replace(idx,u.length(),v);
					idx+=u.length();
					if(flag[ans]) continue;
					flag[ans]=true;
					Q.push(ans);
				}	
			}
		}
	}
	return 11;
}
int main(void)
{
	cin>>a>>b;
	string u,v;
	while(cin>>u>>v)
		V.push_back({u,v});
	
	int Min=bfs();
	if(Min>10) cout<<"NO ANSWER!";
	else cout<<Min-1;
}

P1525 [NOIP2010 提高组] 关押罪犯

二分图+二分排序

#include<bits/stdc++.h>
using namespace std;

const int N=2e5+10;
int idx=0;
int h[N],ne[6*N],e[6*N],w[6*N];
vector<int> V;
bool flag[N];
int color[N];
bool ok;
int n,m;

void add(int u,int v,int d)
{
	ne[idx]=h[u];
	e[idx]=v;
	w[idx]=d;
	h[u]=idx++;
}

void dfs(int dist,int t)
{
	if(!ok)
		return ;
	for(int i=h[t];i!=-1;i=ne[i]){
		int v=e[i],d=w[i];
		if(d>dist){
			if(!flag[v]){
				if(color[t]==1)
					color[v]=2;
				else
					color[v]=1;
				flag[v]=true;
				dfs(dist,v);
			}
			else{
				if(color[v]==color[t]){
					ok=false;
				}
			}
		}
	}
}
void check(int mid)
{
	memset(color,0,sizeof(color));
	memset(flag,false,sizeof(flag));
	ok=true;
	int dist=V[mid];
	for(int i=1;i<=n;i++){
		if(ok&&!flag[i]){
			color[i]=1;
			dfs(dist,i);
		}
	}
		
}
int main(void)
{	
	memset(h,-1,sizeof(h));
	cin>>n>>m;
	for(int i=0;i<m;i++){
		int a,b,c;
		cin>>a>>b>>c;
		add(a,b,c);
		add(b,a,c);
		V.push_back(c);
	}
	sort(V.begin(),V.end());
	if(n==2)
		cout<<0;
	else{
		int l=0,r=V.size()-1;
		while(l<r){
			int mid=l+r>>1;
			check(mid);
			if(ok)
				r=mid;
			else
				l=mid+1;
		}
		cout<<V[l];
	}
	
}

P1955 [NOI2015] 程序自动分析

并查集,解决逻辑矛盾问题

#include<bits/stdc++.h>
using namespace std;

const int N=1e6+10;
int fa[N];
int n;
struct Node{
	Node(){
	}
	Node(int u,int v,int d){
		x=u;
		y=v;
		e=d;
	}
	int x,y,e;
};
struct Node a[N];
vector<int> book;

void init(int n)
{
	for(int i=0;i<=n;i++)
		fa[i]=i;
}

int Find(int x)
{
	if(x==fa[x])
		return fa[x];
	return fa[x]=Find(fa[x]);
}

bool cmp(struct Node A,struct Node B)
{
	return A.e>B.e;
}

int main(void)
{
	int T;cin>>T;
	
	while(T--){
		int cnt=0;
		bool ok=false;
		cin>>n;
		
		for(int i=0;i<n;i++){
			int u,v,d;
			cin>>u>>v>>d;
			a[i]={u,v,d};
			book.push_back(u);
			book.push_back(v);
		}
		
		sort(book.begin(),book.end());
		book.erase(unique(book.begin(),book.end()),book.end());
		init(book.size());
		for(int i=0;i<n;i++){
			a[i].x=lower_bound(book.begin(),book.end(),a[i].x)-book.begin();
			a[i].y=lower_bound(book.begin(),book.end(),a[i].y)-book.begin();
		}
		sort(a,a+n,cmp);
		for(int i=0;i<n;i++){
			int u=Find(a[i].x),v=Find(a[i].y);
			if(a[i].e){
				if(u!=v)
					fa[u]=v;
			}
			else if(u==v){
				printf("NO\n");
				ok=true;
				break;
			}
		}
		if(!ok) cout<<"YES"<<endl;
		book.clear();
	}	
}

P2234 [HNOI2002] 营业额统计

与第一题类似。

#include<bits/stdc++.h>
using namespace std;

const int inf=0x7f7f7f7f;
set<int> S;
int main(void)
{
	S.insert(inf);S.insert(-inf);
	int n;cin>>n;
	int num;cin>>num;
	S.insert(num);
	int Sum=num;
	for(int i=1;i<n;i++){
		cin>>num;
		auto it=S.lower_bound(num);
		int p=*it;
		int q=*(--it);
//		cout<<"----  "<<p<<endl;
		Sum+=min(abs(num-p),abs(num-q));
		S.insert(num);
	}
	cout<<Sum<<endl;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值