【NOIP2017】Day1

来源:互联网 发布:mac百度云离线下载 编辑:程序博客网 时间:2024/06/06 00:42

题目传送门(请点击开头目录)
http://blog.csdn.net/lhq_er/article/details/76693851

Solution

T1:排完序后贪心比较
T2:dp[t][i][j]表示t时间能否一个为一个为j,转移方程很好写。
T3:
30%:建图后最小生成树
100%:Kruskal慢在最所有边排序,其实很多边权值是相同的,所以对行列单独排序,再取,取的时候要注意去重,不多说了

CODE

//T1;#include<cstdio>#include<algorithm>#include<cmath>using namespace std;#define ll long longconst int MAXN=50005;int a[MAXN],b[MAXN];bool flag[MAXN*2];int n,m;int main(){    freopen("cards.in","r",stdin);    freopen("cards.out","w",stdout);    scanf("%d",&n);    for (int i=1;i<=n;i++)    {        scanf("%d",&a[i]);        flag[a[i]]=true;    }       for (int i=1;i<=n+n;i++)        if (!flag[i]) b[++m]=i;    sort(a+1,a+1+n);    sort(b+1,b+1+m);    int j=n,i=0;    for (i=n;i>=1;i--)    {        while (j>=1 && a[j]>b[i]) j--;        if (j<1) break;        j--;    }    printf("%d\n",n-i);     return 0;}
//T2;#include<cstdio>#include<algorithm>#include<cmath>using namespace std;#define ll long longconst int MAXN=105;int n,m,d,t,ans=0x3f3f3f3f;bool f[MAXN][MAXN][MAXN];int main(){    freopen("cups.in","r",stdin);    freopen("cups.out","w",stdout);    scanf("%d%d%d%d",&n,&m,&t,&d);    f[0][0][0]=true;    for (int i=0;i<t;i++)        for (int j=0;j<=n;j++)            for (int k=0;k<=m;k++)            {                if (!f[i][j][k]) continue;                f[i+1][0][k]=true;                f[i+1][j][0]=true;                f[i+1][n][k]=true;                f[i+1][j][m]=true;                if (j>=m-k) f[i+1][j-(m-k)][m]=true;                else f[i+1][0][k+j]=true;                if (k>=n-j) f[i+1][n][m-(n-j)]=true;                else f[i+1][j+k][0]=true;                           }    for (int j=0;j<=n;j++)        for (int k=0;k<=m;k++)            if (f[t][j][k])                ans=min(ans,abs(j+k-d));    printf("%d\n",ans);     return 0;}
//T3;#include<cstdio>#include<algorithm>#include<cmath>using namespace std;#define ll long longconst int MAXN=50005;ll x[MAXN],y[MAXN],row[MAXN],col[MAXN],num[2];ll A,B,n,m,ans=0,last=0,cnt;struct node{    ll v,k;}d[MAXN];bool cmp(const node &x,const node &y){    if (x.v!=y.v) return x.v<y.v;    return x.k<y.k;}int main(){    freopen("spicychicken.in","r",stdin);    freopen("spicychicken.out","w",stdout);    scanf("%lld%lld%lld%lld",&A,&B,&n,&m);    for (ll i=1;i<=n;i++)        scanf("%lld",&x[i]);    for (ll j=1;j<=m;j++)        scanf("%lld",&y[j]);    x[n+1]=A; y[m+1]=B;    sort(x+1,x+1+n);    sort(y+1,y+1+m);    for (ll i=0;i<=n;i++)        row[i]=x[i+1]-x[i],d[i].v=row[i],d[i].k=0;    for (ll j=0;j<=m;j++)        col[j]=y[j+1]-y[j],d[j+n+1].v=col[j],d[j+n+1].k=1;    sort(d,d+n+m+2,cmp);    cnt=(n+1)*(m+1)-1;    for (ll i=0;i<n+m+2 && cnt;i++)    {        if (!num[0] || !num[1])        {            if (d[i].k==0) ans+=m*d[i].v,cnt-=m,num[0]++;            else ans+=n*d[i].v,cnt-=n,num[1]++;            continue;        }        if (d[i].k==0) ans+=(m-num[1]+1)*d[i].v,cnt-=m-num[1]+1,num[0]++;        else ans+=(n-num[0]+1)*d[i].v,cnt-=n-num[0]+1,num[1]++;        last=d[i].v;    }    if (cnt<0) ans-=last*abs(cnt);    printf("%lld\n",ans);    return 0;}
原创粉丝点击