CSP真题(在更)

        由于CSP官网上不能看提交过的代码,把写过题的代码在这里记录一下当个备忘录,以便日后复习(1.2题简单的就不记录了,记录下需要思考的2题和3~5题)


2022-6

角色授权

#include<bits/stdc++.h>
using namespace std;
const int N=505,M=1e3+5;
typedef long long ll;
int n,m,q;
struct User{
	string name;
	int nv;//操作
	set<string> op;
	int no;//资源种类
	set<string> rsc_kind;
	int nn;//资源名称
	set<string> rsc_name;
}user[N]; 
unordered_map<string,int> id;

unordered_map<string,vector<int> >usertoid;
unordered_map<string,vector<int> >grouptoid;
int main(){
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin>>n>>m>>q;
	for(int i=1;i<=n;i++){
		cin>>user[i].name;id[user[i].name]=i;
		cin>>user[i].nv;
		for(int j=0;j<user[i].nv;j++){
			string op;cin>>op;
			user[i].op.insert(op);
		}
		cin>>user[i].no;
		for(int j=0;j<user[i].no;j++){
			string kd;cin>>kd;
			user[i].rsc_kind.insert(kd);
		}
		cin>>user[i].nn;
		for(int j=0;j<user[i].nn;j++){
			string rsc;cin>>rsc;
			user[i].rsc_name.insert(rsc);	
		}
	}
	for(int i=0;i<m;i++){
		string name;cin>>name;int pid=id[name];
		int ns;cin>>ns;
		for(int j=0;j<ns;j++){
			string kd;cin>>kd;
			if(kd=="u"){
				string uname;cin>>uname;
				usertoid[uname].push_back(pid);
			}else{
				string gname;cin>>gname;
				grouptoid[gname].push_back(pid);
			}		
		}
	}
	while(q--){
		string name;cin>>name;
		int ng;cin>>ng;string grp[M];
		for(int i=0;i<ng;i++) cin>>grp[i];
		string n_op,n_kd,n_rsc;cin>>n_op>>n_kd>>n_rsc;
		
		bool bl=false;
		for (int ppid: usertoid[name]){
			if(user[ppid].op.count(n_op)||user[ppid].op.count("*")){
				if(user[ppid].rsc_kind.count(n_kd)||user[ppid].rsc_kind.count("*")){
					if(user[ppid].rsc_name.count(n_rsc)||!user[ppid].rsc_name.size()){
						cout<<1<<endl;
						bl=true;
						break;
					}
				}
			}
		}
		if(bl) continue;

		for(int i=0;i<ng;i++){
			string gname=grp[i];
			for(auto ppid:grouptoid[gname]){
				if(user[ppid].op.count(n_op)||user[ppid].op.count("*")){
					if(user[ppid].rsc_kind.count(n_kd)||user[ppid].rsc_kind.count("*")){
						if(user[ppid].rsc_name.count(n_rsc)||user[ppid].rsc_name.empty()){
							cout<<1<<endl;
							bl=true;
							break;
						}
					}
				}
			}
			if(bl) break;
		}
		if(!bl) cout<<0<<endl;
		
	}
	
}

 2022-3

通信系统管理  暴力TLE 20

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
typedef long long ll;
typedef pair<pair<int,int>,pair<ll,ll> > PIII;
typedef pair<int,int> PII;
int n,m;
set<PIII> st;
map<PII,ll> mp;
map<PII,bool> bl;
ll has[N];
int h[N],e[N<<1],ne[N<<1],idx;
void add(int a,int b){
	e[idx]=b;
	ne[idx]=h[a];
	h[a]=idx++;
}
void op(){
	set<PIII> st1;
	for(auto t:st){
		int u=t.first.first,v=t.first.second;
		ll x=t.second.first;
		ll y=t.second.second;
		if(y==0){
			mp[{u,v}]-=x;
			has[u]-=x;
			has[v]-=x;
			continue;
		}
		else{
			t.second.second-=1;
			st1.insert(t);
		}
	}
	st=st1;
}
int find(int t){
	ll maxn=0;int res=0;
	for(int i=h[t];~i;i=ne[i]){
		int j=e[i];
		ll hs=mp[{t,j}]+mp[{j,t}];
		if(hs>maxn){
			maxn=hs;
			res=j;
		}else if(hs==maxn&&j<res){
			res=j;
		}
	}
	return res;
}
int find1(){
	int res=0;
	for(int i=1;i<=n;i++){
		if(!has[i]) res++;
	}
	return res;
}
int find2(){
	int res=0;
	unordered_map<int,int> tmp;
	for(int i=1;i<=n;i++){
		tmp[i]=find(i);
	}
	for(int i=1;i<=n;i++){
		if(tmp[i]==0) continue;
		if(i==tmp[tmp[i]]){
			res++;
		}
	}
	return res/2;
}
int main(){
	//freopen("1.txt","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>n>>m;
	memset(h,-1,sizeof h);
	for(int i=0;i<m;i++){
		int k;cin>>k;
		op();
		for(int j=0;j<k;j++){
			int u,v,x,y;cin>>u>>v>>x>>y; 
			if(!bl[{u,v}]){
				bl[{u,v}]=bl[{v,u}]=true;
				add(u,v);add(v,u);
			}
			mp[{u,v}]+=x;
			has[u]+=x;
			has[v]+=x;
			st.insert({{u,v},{x,y-1}});
		}
		int l;cin>>l;
		for(int j=0;j<l;j++){
			int t;cin>>t;
			cout<<find(t)<<endl;
		}
		int p,q;cin>>p>>q;
		if(p){
			cout<<find1()<<endl;
		}
		if(q){
			cout<<find2()<<endl;
		}
	} 
	
}
博弈论与石子合并
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
typedef long long ll;
int n,k;
int a[N];
//z先手 偶数堆  或者 c先手 奇数堆
//即z开始操作时面对偶数堆的情况 
//c只能去掉两边的,保持z合并的堆在中间
//最后一步是z将最后两堆合并,所以过程中保持合并的不被c去掉即可
//由于c采取最优策略,所以z剩下的只能是连续的一段最小值 
int fun2(){
	int mid=n/2+1;
	int now=0,res=0;
	for(int i=1;i<=mid;i++){
		now+=a[i];
	}
	res=now;
	for(int i=mid+1;i<=n;i++){
		now+=(a[i]-a[i-mid]);
		res=min(res,now);
	}
	return res;
}
//有多少段的和满足>=x 
bool judge(int x){
	int sum=0,num=0;
	for(int i=1;i<=n;i++){
		sum+=a[i];
		if(sum>=x){
			sum=0;
			num++;
		}
	}
	return num>n/2; 
}
//c最多操作n/2次
//找到满足段数>=n/2 段和x取最大值
//最后至少会剩下一段x 
int fun1(){
	int l=1,r=1e9;
	while(l<r){
		int mid=l+r+1>>1;
		if(judge(mid)) l=mid;
		else r=mid-1; 
	}
	return l;
}
int main(){
	cin>>n>>k; 
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	int res=0;
	int l=1,r=n;
	if(!k){//c先手 
		if(n&1) res=fun2(); 
		else res=fun1();
		
	}else{//z先手 
		if(n&1) res=fun1(); 
		else res=fun2();
	}
	cout<<res;
}


2021-12

序列查询

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
const int N=1e7+5;
int n,m,a[N];
map<int,int> mp;
typedef long long ll;
ll res;
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i],mp[a[i]]=i;
	sort(a,a+n+1);
	a[n+1]=m;
	for(int i=1;i<=n;i++)
		res+=mp[a[i]]*(a[i+1]-a[i]);
	cout<<res;
}

 序列查询新解

未优化(70分)

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
const int N=1e7+5;
typedef long long ll;
ll n,m,a[N];
map<ll,ll> mp;
ll res,r; 
int main()
{
	cin>>n>>m;
	r=m/(n+1);
	mp[0]=0;
	for(ll i=1;i<=n;i++) cin>>a[i],mp[a[i]]=i;
	sort(a,a+n+1);
	a[n+1]=m;
	for(ll i=0;i<=n;i++)
	{
		for(ll x=a[i];x<a[i+1];x++)
		{
			ll g=x/r;
			res+=abs(g-mp[a[i]]);
		}	
	}
	cout<<res;
}

优化后(100分)

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
const int N=1e5+5;
typedef long long ll;
ll n,m,a[N];
map<ll,ll> mp;
ll res;
ll r;
int main()
{
	cin>>n>>m;
	r=m/(n+1);
	mp[0]=0;
	for(ll i=1;i<=n;i++) cin>>a[i],mp[a[i]]=i;
	sort(a,a+n+1);
	a[n+1]=m;
	for(ll i=0;i<=n;i++)
	{
		for(ll x=a[i];x<a[i+1];)
		{
			ll g=x/r;
			ll cnt=r-x%r;
			cnt=min(cnt,a[i+1]-x);
			res+=cnt*abs(g-mp[a[i]]);
			x+=cnt;
		}	
	}
	cout<<res;
}

极差路径(xjb-dfs的12分)

#include<bits/stdc++.h>
#include<map>
using namespace std;
const int N=5e5+5,M=N*2;
int n,k1,k2;
int h[N],e[M],ne[M],idx;
int res;
void add(int a,int b)
{
	e[idx]=b;
	ne[idx]=h[a];
	h[a]=idx++;
}
typedef pair<int,int> PII;
map<PII,bool> mp;

// st-u  
void dfs(int u,int pre,int st,int best,int worst)
{
	int tb,tw;
	tb=min(best,u),tw=max(worst,u);
	if(tb>=min(st,u)-k1&&tw<=max(st,u)+k2&&tw>=tb)
	{
		if(!mp[{st,u}]&&!mp[{u,st}])
		{
			res++;
			mp[{st,u}]=mp[{u,st}]=true;
			//cout<<st<<" "<<u<<endl;	
		}
	}
	for(int i=h[u];i!=-1;i=ne[i])
	{
		int j=e[i];
		if(j==pre) continue;
		dfs(j,u,st,tb,tw);
	}
}
int main()
{
	cin>>n>>k1>>k2;
	memset(h,-1,sizeof h);
	for(int i=0;i<n-1;i++)
	{
		int a,b;cin>>a>>b;
		add(a,b),add(b,a);
	}
	for(int i=1;i<=n;i++) 
		dfs(i,-1,i,i,i);
	cout<<res;
} 

把无脑去重改为了起点<终点的剪枝 (16分)

#include<bits/stdc++.h>
#include<map>
using namespace std;
const int N=5e5+5,M=N*2;
int n,k1,k2;
int h[N],e[M],ne[M],idx;
int res;
void add(int a,int b)
{
	e[idx]=b;
	ne[idx]=h[a];
	h[a]=idx++;
}
// st-u  
//当前位置  父节点  起点  最小界  路径中的最大值 
void dfs(int u,int pre,int st,int best,int worst)
{	
	if(u>=st&&u+k2>=worst) res++;
	if(u<best) return;
	for(int i=h[u];i!=-1;i=ne[i])
	{
		int j=e[i];
		if(j==pre) continue;
		dfs(j,u,st,best,max(worst,u));
	}
}
int main()
{
	cin>>n>>k1>>k2;
	memset(h,-1,sizeof h);
	for(int i=0;i<n-1;i++)
	{
		int a,b;cin>>a>>b;
		add(a,b),add(b,a);
	}
	for(int i=1;i<=n;i++) 
		dfs(i,-1,i,i-k1,i);
	cout<<res;
} 

2021-09

非零段划分

#include<iostream>
using namespace std;
const int N=5e5+5;
int n,a[N];
int cnt[N];
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		if(a[i]>a[i-1])
		{
			cnt[a[i]+1]--;
			cnt[a[i-1]+1]++;
		}
	}
	int res=0,maxn=-1;
	for(int i=1;i<=5e5;i++) 
	{
		res+=cnt[i];
		maxn=max(res,maxn);
	}
	cout<<maxn;
} 

收集卡牌(状压DP)

#include <bits/stdc++.h>
using namespace std;
const int N=17,M=1<<N;
long double p[N];
int n,k;
long double res;
long double f[M][85];
//最多16个卡,最多5个硬币换一个,所以抽的次数<80 
int main()
{
	cin>>n>>k;
	for(int i=0;i<n;i++) cin>>p[i];
	f[0][0]=1;
	for(int t=0;t<77;t++)//按次数 
		for(int st=0;st<(1<<n);st++)
		{
			int cnt=0;
			for(int i=0;i<n;i++)
				if(st>>i&1) cnt++;
			if((n-cnt)*k<=t-cnt)
			{
				res+=f[st][t]*t;
				continue;
			}
			for(int i=0;i<n;i++)
				f[st|(1<<i)][t+1]+=f[st][t]*p[i];
		}		
	cout<<fixed<<setprecision(10)<<res;
}


2021-04

邻域均值(暴力70分,二维前缀和100分,注意边界)

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N=1e3+5;
int n,l,r,t;
int w[N][N];
int res;
void solve(int a,int b)
{
	int cnt=0,sum=0;
	int x1=min(a+r,n),y1=min(b+r,n);
	int x2=max(a-r,0),y2=max(b-r,0);
	int tx=x1-x2,ty=y1-y2;
	if(x2!=0) tx++;
	if(y2!=0) ty++; 
	cnt=tx*ty;
	sum=w[x1][y1]+w[max(x2-1,0)][max(y2-1,0)]-w[max(x2-1,0)][y1]-w[x1][max(y2-1,0)];
	//cout<<a<<"-"<<b<<" "<<tx<<"-"<<ty<<" "<<cnt<<"-"<<sum<<endl;
	if(sum*1.0/cnt<=t) res++;
}
int main()
{
	cin>>n>>l>>r>>t;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		{
			cin>>w[i][j];
			w[i][j]=w[i][j]+w[i-1][j]+w[i][j-1]-w[i-1][j-1];
		}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			solve(i,j);
	cout<<res;
}

 校门外的树(DP)

#include<iostream>
#include<cstdio> 
#include<vector>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=1e5+5;
const ll mod=1e9+7;
int n,w[N];
bool st[M];
vector<int> q[M];//每个数的所有约数 
ll f[N];//f[i]表示前i个节点的区间可行解个数
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>w[i];
	
	for(int i=1;i<M;i++)
		for(int j=i*2;j<M;j+=i)
			q[j].push_back(i);
	
	f[1]=1;
	for(int i=2;i<=n;i++)
	{
		memset(st,false,sizeof st);
		for(int j=i-1;j>=1;j--)
		{
			int d=w[i]-w[j];
			int cnt=0;
			for(int k:q[d])
				if(!st[k])
				{
					cnt++;
					st[k]=true;
				}
			st[d]=true;
			f[i]=(f[i]+(ll)f[j]*cnt)%mod;
		}
	}
	cout<<f[n];
} 

 疫苗运输(暴力dfs 80分)

#include<iostream>
using namespace std;
int n,m;
const int T=1e6+5;
//当前位置  下一位置  需要时间 
typedef pair<pair<int,int>,int> PII;
PII nex[35][T];//第i条路线 时间为t时 
bool vis[35][T];
int dis[35];
int zd[35],sj[35];
void dfs(int x,int t)
{
	if(t>=T) return;
	if(vis[x][t]) return;
	vis[x][t]=true;
	if(dis[x]>t) dis[x]=t;
	for(int i=0;i<m;i++)
		if(nex[i][t].first.first==x)
			dfs(nex[i][t].first.second,t+nex[i][t].second);
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++) dis[i]=T;
	for(int i=0;i<m;i++) 
	{
		int k;cin>>k;
		for(int j=0;j<k;j++) cin>>zd[j]>>sj[j];
		int x=0,t=0;
		while(t<T)
		{
			nex[i][t]={{zd[x],zd[(x+1)%k]},sj[x]};
			t+=sj[x];
			x=(x+1)%k;
		}	
	}
	for(int i=0;i<T;i++) dfs(1,i);
	for(int i=2;i<=n;i++)
		if(dis[i]==T) cout<<"inf"<<endl;
		else cout<<dis[i]<<endl;
}

2020-12

期末预测之最佳阈值(前缀和)

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N=1e8+5,M=1e5+5;
int n,m;
int w[M],y;
int b[N];
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>w[i]>>y;
		m=max(m,w[i]);
		if(!y) b[w[i]+1]++;
		else
		{
			b[1]++;
			b[w[i]+1]--;
		}
	}
	sort(w+1,w+n+1);
	for(int i=1;i<=m;i++) b[i]+=b[i-1];
	int res=0,cnt=0;
	for(int i=1;i<=n;i++)
	{
		if(b[w[i]]>=cnt)
		{
			cnt=b[w[i]];
			res=w[i];
		}
	}
	cout<<res;
	return 0;
}

食材运输(状压DP+dfs)

#include<bits/stdc++.h>
using namespace std;
const int N=105,M=N*2;
int n,m,k;
int fd[N][15];
int h[N],e[M],ne[M],w[M],idx;
int state[1<<11];
int dp[1<<11];
int d[N][15];//第i个酒店出发,给所有需要j食材的运输距离
//对d[i][j] 来说
//考虑回到原点,那么记A为从i走到所有需要j食材酒单的两倍路径和
//如果不回到原点,那么就是找到离i最远的需要食材j的酒店,记此距离为a
//那么d[i][j] = A - a; 两次dfs即可 
void add(int a,int b,int c)
{
	e[idx]=b;
	w[idx]=c;
	ne[idx]=h[a];
	h[a]=idx++;
}
int dfs1(int u,int fa,int food)
{
	int res=0;
	for(int i = h[u]; ~i; i = ne[i])
	{
        int j = e[i];
        if(j == fa) continue;
        int t = dfs1(j,u,food);
        if(t)//子树中有节点需要 
        	res+=t+2*w[i];
        else if(fd[j][food])//子节点需要 
			res+=w[i]*2; 
    }
    return res;
} 
int dfs2(int u,int fa,int food)
{
	int res=0;
	for(int i = h[u]; ~i; i = ne[i])
	{
        int j = e[i];
        if(j == fa) continue;
        int t = dfs2(j,u,food);
        if(t||fd[j][food])
			res=max(res,t+w[i]);
    }
    return res;
} 
bool check(int x)
{
	memset(state,0,sizeof state);
    for(int i = 1; i<=n; i++)
        for(int j = 0; j<k; j++)
            if(d[i][j] <= x) state[i] |= 1 << j;
	memset(dp,0x3f,sizeof dp);
    dp[0] = 0;//dp[i] 此时送到的状态为i,对应需要点的个数 
    for(int i=0;i<1<<k;i++)
    	for(int j=1;j<=n;j++)
    		dp[i|state[j]]=min(dp[i|state[j]],dp[i]+1);
	//判断点的个数是否<=m 
	return dp[(1<<k)-1]<=m;
}
int main()
{
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++)
		for(int j=0;j<k;j++)
			cin>>fd[i][j];
	memset(h,-1,sizeof h);
	for(int i=0;i<n-1;i++)
	{
		int a,b,c;cin>>a>>b>>c;
		add(a,b,c),add(b,a,c);
	}
	for(int i = 1; i<=n; i++)
        for(int j = 0; j<k; j++)
            d[i][j] = dfs1(i,-1,j) - dfs2(i,-1,j);
	
	int l = 0, r = 1e9;
    while(l<r)
	{
        int mid = (l+r)>>1;
        if(check(mid)) r = mid;
        else l = mid + 1;
    }
    cout<<l<<endl;
}

2019-12

化学方程式(大模拟)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
string str;
typedef unordered_map<string,int> mp;
mp m_map;
int get(string s)
{
	int t=0;
	for(int i=0;i<s.length();i++)
		t*=10,t+=s[i]-'0';
	return t;
}
mp dfs(string &s,int &pos)
{
    mp res;
    while(pos<s.length())
    {
    	if(s[pos]=='(')
    	{
    		pos++;
    		mp tr=dfs(s,pos);
    		pos++;
    		int t=1,k=pos;
    		while(k<s.size()&&isdigit(s[k])) k++;
    		if(k>pos)
    		{
    			t=get(s.substr(pos,k-pos));
    			pos=k;
    		}
    		for(auto x:tr)
    			res[x.first]+=x.second*t;
    	}
    	else if(s[pos]==')') break;
    	else
    	{
    		int k=pos+1;
    		while(k<s.size()&&islower(s[k])) k++;
    		string ts=s.substr(pos,k-pos);
    		pos=k;
    		int t=1;
    		while(k<s.size()&&isdigit(s[k])) k++;
    		if(k>pos)
    		{
    			t=get(s.substr(pos,k-pos));
    			pos=k;
    		}
    		res[ts]+=t;
    	}
    }
    return res;
}
void check(string s,int flag)
{
	int t=1;
	int pos=0;
	int len=s.length();
	while(pos<len&&isdigit(s[pos])) pos++;
	if(pos) t=get(s.substr(0,pos));
	
	mp d=dfs(s,pos);
	for(auto x:d)
		m_map[x.first]+=(flag)*t*x.second;
}
void solve()
{
	int len=str.length();
	string t="";
	int flag=-1;
	for(int i=0;i<len;i++)
	{
		if(str[i]=='+')
		{
			check(t,flag);
			t="";
		}
		else if(str[i]=='=')
		{
			check(t,flag),flag=1;
			t="";
		}
		else t+=str[i];
	}
	check(t,flag);
}
int main()
{
	cin>>n;getchar();
	for(int i=0;i<n;i++)
	{
		getline(cin,str);
		m_map.clear();
		solve();
		bool f=false;
		for(auto x:m_map) 
			if(x.second!=0)
			{
				cout<<"N"<<endl;
				f=true;
				break;
			}
		if(f) continue;
		cout<<"Y"<<endl;
	}
}

区块链(可持久化链表)

#include<iostream>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<vector>
#include<queue>
using namespace std;
typedef vector<int> vc;
const int  N=510, M=20010;
int h[N], e[M], ne[M], idx;
int n,m,q,w;
int node[N];//记录每个节点的主链编号 
vector<vc>g;//存储所有的链表
struct op
{
  int t, id, pid, hid; 
//更新时间  目标编号  自身编号  此刻自身主链编号 
  bool operator <(const op &r)const
  {
      return r.t<t;
  }
}; 
priority_queue<op>heap;
void add(int a,int b)
{
    e[idx]=b; ne[idx]=h[a]; h[a]=idx++;
}
void eval()
{
	op t=heap.top();heap.pop();
	vector<int> a,b;//目标链的主链  发送来的主链 
	a=g[node[t.id]],b=g[t.hid];
	if(b.size()>a.size()||b.size()==a.size()&&a.back()>b.back())
	{
		node[t.id]=t.hid;//更新主链 
		for(int i=h[t.id];~i;i=ne[i])
        {
            if(e[i]!=t.id&&e[i]!=t.pid)//忽略自环和父节点 
                heap.push({t.t+w, e[i], t.id, t.hid});
        }	
	}	
} 

int main()
{
    scanf("%d%d",&n,&m);
    g.push_back({0});
    memset(h,-1,sizeof h);
    while(m--)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        add(a,b); add(b,a);
    }
    scanf("%d%d",&w,&q);
    getchar();string s;
    while(q--)
    {
        getline(cin,s);
        stringstream ssin(s); //初始化
        int a[3], cnt=0;
        while(ssin>>a[cnt]) cnt++;
        if(cnt==3)
        {
             while(heap.size()&&heap.top().t<=a[1]) eval();
             g.push_back(g[node[a[0]]]);//复制一条主链 
			 g.back().push_back(a[2]);//在复制的主链上更新 
             node[a[0]]=g.size()-1;//更新主链编号 
             for(int i=h[a[0]]; ~i;i=ne[i])
                if(e[i]!=a[0])//更新邻居,避免自环 
                    heap.push({a[1]+w, e[i], a[0], node[a[0]]});
        }
        else
        {
            while(heap.size()&&heap.top().t<=a[1]) eval();
            printf("%d ",g[node[a[0]]].size());
            for(int i=0;i<g[node[a[0]]].size();i++)
				cout<<g[node[a[0]]][i]<<" ";
            puts("");
        }

    }

    return 0;
}

2018-12

数据中心(最小生成树的最大边,kruskal)

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;;
struct edge
{
	int a,b,w;
}ed[N];
bool cmp(edge a,edge b)
{
	return a.w<b.w;
}
int n,m,rt,p[N];
int res;
int find(int x)
{
	if(p[x]!=x) p[x]=find(p[x]);
	return p[x];
}
void kruskal()
{
	for(int i=1;i<=m;i++)
	{
		edge t=ed[i];
		int a=t.a,b=t.b,w=t.w;
		a=find(a),b=find(b);
		if(a==b) continue;
		p[a]=b;
		res=w;
	}
}
int main()
{
	cin>>n>>m>>rt;
	for(int i=1;i<=n;i++) p[i]=i;
	for(int i=1;i<=m;i++)
	{
		int a,b,w;cin>>a>>b>>w;
		ed[i]={a,b,w};
	}
	sort(ed+1,ed+m+1,cmp);
	kruskal();
	cout<<res;
}

2018-9

再卖菜(搜索剪枝了一波,超时80分)

#include<bits/stdc++.h>
using namespace std;
const int N=5005,M=N*5;
int w[N],res[N];
int n;
//第u个数为t 
bool dfs(int u,int t)
{
	if(u==n+1)
	{
		if((res[n-1]+res[n])/2!=w[n]) return false;
		return true;	
	}
	if(u==2)
	{
		t=max(2*w[1]-res[1],1);
		while((res[1]+t)/2<w[1]) t++;
		while((res[1]+t)/2==w[1])
		{
			res[u]=t;
			if(dfs(u+1,1)) return true;
			else t++; 
		}
		if((res[1]+t)/2>w[1]) return false;
	}
	if(u!=1)
	{
		t=max(3*w[u-1]-res[u-1]-res[u-2],1);
		while((res[u-1]+res[u-2]+t)/3<w[u-1]) t++;
		while((res[u-1]+res[u-2]+t)/3==w[u-1])
		{
			res[u]=t;
			if(dfs(u+1,1)) return true;
			else t++; 
		}
		if((res[u-1]+res[u-2]+t)/3>w[u-1]) return false;
	}
	for(int i=1;;i++)
	{
		res[1]=i;
		if(dfs(u+1,1)) 
			return true;
	}
	
}
int main()
{	
	cin>>n;
	for(int i=1;i<=n;i++) cin>>w[i];
	dfs(1,1);
	for(int i=1;i<=n;i++)
	{
		cout<<res[i];
		if(i!=n) cout<<" ";
	}
}

2018-3

棋盘评估

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int M = 1e9;
const int N = -1e9;
int a[10][10];
bool judge(int num);
int DFS(int k);
int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		for (int i = 1; i <= 3; i++)
		{
			for (int j = 1; j <= 3; j++)
			{
				scanf("%d", &a[i][j]);
			}
		}
		cout << DFS(1) << endl;
	}
	return 0;
}
int DFS(int k)
{
	int cnt = 0;
	int Max = N;
	int Min = M;
	for (int i = 1; i <= 3; i++)
	{
		for (int j = 1; j <= 3; j++)
		{
			if (a[i][j] == 0)
				cnt++;
		}
	}
	if ((k == 1) && judge(2))
		return -cnt - 1;
	if ((k == 2) && judge(1))
		return cnt + 1;
	if (cnt == 0)
		return 0;
	for (int i = 1; i <= 3; i++)
	{
		for (int j = 1; j <= 3; j++)
		{
			if (a[i][j] == 0)
			{
				a[i][j] = k;
				if (k == 1)
				{
					Max = max(Max, DFS(2));
				}
				else
				{
					Min = min(Min, DFS(1));
				}
				a[i][j] = 0;
			}
		}
	}
	if (k == 1)
		return Max;
	else
		return Min;
}
bool judge(int num)
{
	for (int i = 1; i <= 3; i++)
	{
		if (a[i][1] == num && a[i][2] == num && a[i][3] == num)
			return true;
		if (a[1][i] == num && a[2][i] == num && a[3][i] == num)
			return true;
	}
	if (a[1][1] == num && a[2][2] == num && a[3][3] == num)
		return true;
	if (a[1][3] == num && a[2][2] == num && a[3][1] == num)
		return true;
	return false;
}

### 回答1: CCF(中国计算机学会) CSP(计算机软件能力认证)认证真题是一种针对计算机软件开发人员的职业能力认证考试。该考试旨在通过检测考生的计算机软件开发技能水平,评估其能否胜任相应的职业岗位。 CCF CSP认证真题主要考察考生的编程能力、算法分析与设计能力、操作系统与架构知识等方面。考试难度较高,需要考生具备扎实的计算机基础知识、广泛的软件开发经验和良好的解决问题能力。同时,考生还需要具备严密的逻辑思维和高超的编程技巧,才能在考试中取得良好的成绩。 CCF CSP认证真题证书具有较高的认可度和职业价值,拥有该证书可以为求职者提供好的职业机会和高的薪资待遇。同时,该证书也可以为企业提供高水平的软件开发人才,增强企业的竞争力。 总之,CCF CSP认证真题是一项重要的软件开发人才认证考试,对于求职者和企业来说都有重要的价值。 ### 回答2: CCF CSP认证真题,是指由中国计算机学会主办的计算机技术认证考试,该认证考试分为初、中、高三个级别,考试内容涉及计算机程序设计、算法数据结构、操作系统、计算机网络、数据库等多个方面,是全面考察计算机技术能力的认证考试。 CCF CSP认证真题,具有以下特点: 1. 面向实际问题:CCF CSP认证真题不仅关注计算机理论知识,注重将计算机理论知识应用于实际问题中解决问题的能力。 2. 全面覆盖:CCF CSP认证真题涉及计算机程序设计、算法数据结构、操作系统、计算机网络、数据库等多个方面,全面覆盖了计算机技术的核心领域。 3. 考察深度与广度:CCF CSP认证真题设计考察深度与广度,考察内容包含基础部分、拓展部分和应用部分,确保考生对计算机技术的理论知识、应用能力和实践经验都有全面的掌握。 4. 高度质量:CCF CSP认证真题严格按照标准组织考试,题目难度逐步递进、稳步上升,考察重点触及计算机技术的核心问题,确保考试的高度质量及合理性。 CCF CSP认证真题是一道非常重要的关卡,通过认证不仅可以获得有力的证明,而且也能够增强个人的专业技能,促进个人在行业内的发展。因此,积极准备并通过CCF CSP认证真题考试,对于提升自身竞争力与技术水平都是非常有益的。 ### 回答3: CCF CSP认证真题,指的是由中国计算机学会(CCF)组织和管理的计算机专业证书考试。CSPCCF推出的“计算机专业技术资格认证”,旨在为从事计算机相关技术工作的人员提供权威认证。 CSP认证真题主要包括CSP-J、CSP-S、CSP-A三个级别,分别对应初级、中级和高级水平。这些考证的特点是真实、准确、有权威性,可以考验考生在计算机理论、操作、产品等方面的综合能力。 从考试内容来看,CSP认证真题涉及到计算机体系结构、数据结构、操作系统、数据库、网络、编程语言等多个方面,考生需要在广泛的计算机知识领域具备一定的深度和广度。在考试前,考生还需要对不同等级的考试内容有充分的了解和准备,以保证通过考试。 对于从事计算机相关工作的人员来说,CSP认证真题是一个十分重要的证书,它可以为职业生涯提供有力的支撑和推动。无论是在职业发展、职业转型还是就业竞争中,拥有CSP认证真题都会具有一定的优势。因此,建议有志于在计算机领域领先的人员积极报考CSP认证真题,努力提高自己的专业水平和竞争力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Vic.GoodLuck

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

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

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

打赏作者

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

抵扣说明:

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

余额充值