洛谷9月noip模拟赛

来源:互联网 发布:淘宝买家可以延长收货 编辑:程序博客网 时间:2024/06/02 02:08

第一题:

求一个排列是第几小(字典序)
用康托展开。
例如 求3214的字典序。
我们从高位开始比较,比3小的有两位,即2*3!=12,再比较下一位2,比2小的只有1,且1没有用过,所以再加1*2!=2,再比较1,没有比1小的数,最后一位因为比它小的树必定已经全部被用过,所以不需要比较。
故3214的字典序为12+2+1=14.
所以对于这道题,我们先预算出1~10的阶乘,然后再康托展开即可。
贴代码:

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>using namespace std;int n,ans,num;string s;int a[11];bool vis[11];int main(){    scanf("%d",&n);    cin>>s;    a[0]=1;    for(int i=1;i<=10;i++)     a[i]=a[i-1]*i;    memset(vis,true,sizeof(vis));    ans=1;    for(int i=0;i<n;i++)    {        int k=s[i]-'0';        vis[k]=false;        num=0;        for(int j=1;j<k;j++)         if(vis[j]==true)num++;        ans+=num*a[n-i-1];    }    cout<<ans<<endl;} 

第二题:

求树上任意两点之间所有边权的异或。
设a,b两点的最近公共祖先为c,题目即为求a~c~b的异或,可以知道x^y^y=x,故只需求a,b到树根的异或的异或,从树根到c的边权异或两次后相当于未运算。
贴代码:

#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>using namespace std;struct Node{    int to,val,next; }e[200005];int head[100005];bool vis[100005];int xo[100005];int tot=0;void add(int u,int v,int w){    e[++tot].to=v;    e[tot].val=w;    e[tot].next=head[u];    head[u]=tot;}void dfs(int u){    vis[u]=true;    for(int i=head[u];i!=0;i=e[i].next)      if(!vis[e[i].to])      {         int v=e[i].to;         xo[v]=xo[u]^e[i].val;         dfs(v);       }}int main(){    int u,v,w,n,m;    scanf("%d",&n);    memset(head,0,sizeof(head));    for(int i=1;i<n;i++)    {        scanf("%d%d%d",&u,&v,&w);        add(u,v,w);        add(v,u,w);     }    xo[u]=0;    dfs(1);    scanf("%d",&m);    for(int i=1;i<=m;i++)    {        scanf("%d%d",&u,&v);        printf("%d\n",xo[u]^xo[v]);    }    return 0;}

第三题:

题目链接:http://www.luogu.org/problem/show?pid=2583
这次考试唯一有价值的题目。
看完题目后,第一感觉是动规,然而自己想了想状态转移方程并没有想出来——>捂脸(其实是状态选择的不太对,造成转移困难)。
于是就去问学长了,学长说是最短路,(i,j)表示第i时刻在第j站,如果原地等待就在(i,j)到(i+1,j)建边
然而接受了学长的教导后,我并没有做出来23333
Golve最后提供了动规的思路%%%
Dp[i][j]表示i时刻,在第j站到达n最少还需等待多长时间。
初始化:dp[t][n]=0;
Dp[t][1~n-1]=INF.
我们还需要一个数组hastrain[i][j][0]表示i时刻j车站有一辆从左到右的火车;
Hastrain[i][j][1]表示i时刻j车站有一辆从右到左的火车。
Hastrain可以在读入时就处理好。
对于题目中的每个点,我们一定是从后更新前,因为最后的状态是确定的(初始化),所以每个点会有三种情况。
1.原地等待 dp[i][j]=dp[i+1][j]+1;
2.从左开向右
满足条件 j< n,hastrain[i][j][0]==true,i+ti[j]<=t
Dp[i][j]=min(dp[i][j],dp[i+ti[j]][j+1]);
3.从右向左开
满足条件j>1,hastrain[i][j][1]==true,i+ti[j-1]<=t
Dp[i][j]=min(dp[i][j],dp[i+ti[j-1]][j-1]);
输出按照格式就可以AC啦。
贴代码:

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>using namespace std;int n,t,m,INF;int ti[60];bool hastrain[300][60][3];int dp[300][53];int main(){    int ca=0;    while(scanf("%d",&n)&&n!=0)    {       ca++;       scanf("%d",&t);       INF=t;       ti[0]=0;       for(int i=1;i<n;i++)        scanf("%d",&ti[i]),INF-=ti[i];       INF+=5;       memset(hastrain,false,sizeof(hastrain));       int x;       scanf("%d",&m);       for(int i=1;i<=m;i++)       {          scanf("%d",&x);          hastrain[x][1][0]=true;          int num=x;          for(int j=1;j<=n;j++)          {             num+=ti[j];             if(num>t)break;             hastrain[num][j+1][0]=true;          }       }       scanf("%d",&m);       for(int i=1;i<=m;i++)       {          scanf("%d",&x);          hastrain[x][n][1]=true;          int num=x;          for(int j=n-1;j>=1;j--)          {             num+=ti[j];             if(num>t)break;             hastrain[num][j][1]=true;          }       }       for(int i=1;i<=n-1;i++)dp[t][i]=INF;       dp[t][n]=0;       for(int i=t-1;i>=0;i--)         for(int j=1;j<=n;j++)         {            dp[i][j]=dp[i+1][j]+1;            if(j<n&&hastrain[i][j][0]&&i+ti[j]<=t)             dp[i][j]=min(dp[i][j],dp[i+ti[j]][j+1]);            if(j>1&&hastrain[i][j][1]&&i+ti[j-1]<=t)             dp[i][j]=min(dp[i][j],dp[i+ti[j-1]][j-1]);         }       cout<<"Case Number "<<ca<<": ";      if(dp[0][1]>=INF)cout<<"impossible\n";      else cout<<dp[0][1]<<"\n";    }    return 0;}

总结:前两道题都是一次通过的,然后最后一道过了5~6遍,得了85.74。
让我们总结一下为什么错这么多遍吧。(错误不分先后,记忆废)
(1)貌似一开始INF设错了,最大应该是总时间t减去通往每个站的时间,但我一开始设为了一个大整数。
(2)然后提交后还是错误,我心想不可能吧,是不是服务器出错了,然后什么都没改又交了一遍(真是傻到无可救药了)
(3)好吧真正错这么多遍的原因是 输!出!格!式!
空格出没的那么诡异真的好吗,好吧,以后做题要把样例复制粘贴观察格式
—————————全剧终——————————————————-

0 0