[校内模拟] 200803Practice NOIP

T1 Tree

映射一下
(话说其实不需要开long long,数据够水)

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=1e6+5;
map<int,int>M;
int n,m;

int main(){
    n=in,m=in;
    for(int i=1;i<=n;++i) ++M[in];
    for(int i=1;i<=m;++i) cout<<M[in]<<" ";
    return 0;
}

top

T2 Transfer

DFS处理环,学到了学到了
注意边界

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

typedef long long ll;
const int N=2e5+5;
int n,aim[N],into,loop[N],cnt,tot;
ll k;
bool vis[N];

void DFS(int u){
    ++tot;
    vis[u]=true;
    if(vis[aim[u]]) into=aim[u];
    else DFS(aim[u]);
    return;
}

void init(){
    DFS(1);
    int u=into;bool tag=false;
    while(true){
        if(u==into&&tag) break;
        tag=true;
        loop[++cnt]=u;
        u=aim[u];
    }loop[0]=loop[cnt];
    return;
}

int main(){
    n=in;scanf("%lld",&k);
    for(int i=1;i<=n;++i) aim[i]=in;
    init();
    if(k<=tot-cnt){
        int ans=1;
        for(int i=1;i<=k;++i) ans=aim[ans];
        cout<<ans<<endl;
    }else{
        k-=tot-cnt-1;
        cout<<loop[k%cnt]<<endl;
    }
    return 0;
}

top

T3 Ship

二分图呗
二分图个鬼
人家求的是航道不交叉qwq

发现:
两条航线起点终点都是小于或大于,航线不相交
对起点排序
求终点的最长不下降序列
数据小,可DP

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=5e3+5;
int n,f[N];
struct node{
    int u,v;
}p[N];

bool cmp(const node a,const node b){
    return a.u<b.u;
}

int main(){
    n=in;
    for(int i=1;i<=n;++i) p[i].u=in,p[i].v=in;
    sort(p+1,p+n+1,cmp);
    for(int i=1;i<=n;++i) f[i]=1;
    for(int i=1;i<=n;++i)
        for(int j=1;j<i;++j){
            if(p[i].v>p[j].v)
                f[i]=max(f[i],f[j]+1);
        }
    int ans=0;
    for(int i=1;i<=n;++i) ans=max(ans,f[i]);
    cout<<ans<<endl;
    return 0;
}

top

T4 Transp

这类题我还真没做过

记搜+剪枝

常见剪枝:

  1. 容量限制
  2. 答案最优

题目有BUG
他没说x可以是实数qwq

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=105;
int n;
double w[N],x,v[N],suf[N],ans;
bool used[N],best[N];

void DFS(int k,double wei,double val){
    if(wei>x) return;
    if(k==n+1){
        if(val>ans){
            ans=val;
            for(int i=1;i<=n;++i) best[i]=used[i];
        }
        return;
    }
    if(val+suf[k]<ans) return;
    used[k]=true;
    DFS(k+1,wei+w[k],val+v[k]);
    used[k]=false;
    DFS(k+1,wei,val);
    return;
}

int main(){
    cin>>x>>n;
    for(int i=1;i<=n;++i) scanf("%lf%lf",&w[i],&v[i]);
    for(int i=n;i>=1;--i) suf[i]=suf[i+1]+v[i];
    DFS(1,0,0);
    cout<<(int)floor(ans)<<endl;
    for(int i=1;i<=n;++i) if(best[i]) cout<<i<<" ";
    return 0;
}

top

T5 Candy

不会的算法(还是太菜qwq
差分约束系统

top

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页