由于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;
}