2022.2.13校内模拟赛题解报告

2022.2.13校内模拟赛题解报告

T1-url

思路:既然每个压缩的串必须比原先的短,还要相同串压缩必须相同,自然想到 STL 的 map 容器,映射一下即可,如何压缩串?考完听 ghc 讲他的 dfs 感觉太复杂了,为什么不直接随机呢,每次 rand%26+97 即可,题目保证有解也就是不可能原串长为 1,则每次rand的次数是 Len-1,比较奇怪的是每次 %26+97 char 出来的数可能不是 a~z 中的字母,需要 while 一下直到是字母为止。

/*
work by : Dreamcatcher
knowledge : 神仙算法
复杂度 : O(过不了)
*/
#include<map>
#include<ctime>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int INF=0x3f3f3f3f;
const int N=2005;

int read() {
    int x=0,f=0;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) f|=(ch=='-');
    for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch&15);
    return f?-x:x;
}

void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(x>9) print(x/10);
    putchar(x%10+48);
}

int n;
string s[N];
map<string,string>Map;

signed main() {
//   freopen("url.in","r",stdin);
//   freopen("url.out","w",stdout);
   n=read();srand(114514);
   for(int i=1;i<=n;++i) cin>>s[i];
   for(int i=1;i<=n;++i){
       if(Map[s[i]]!="")continue; 
       string sss="";char c;
       int Rand=0,Len=s[i].length();
       for(int j=0;j<Len-1;++j){
           do{
               Rand=rand()%26;
               c=Rand+97;
           }while(c<'a'||c>'z'); 
           sss=sss+c;
       }
       Map[s[i]]=sss;
   }
   for(int i=1;i<=n;i++) cout<<Map[s[i]]<<"\n";
   return 0;
}

T2-异构体

怎么说,考试的时候有思路,奈何码力太差,写不出来,于是就只判了一种情况,得了50pts。后来翻了翻学长的提交记录,发现 lps 的思路和我的一模一样,于是学习了一下。

主要思路如下:题目中描述的是一棵树,只不过被人多加了一笔,有环了或者有个点的入度等于2了,做法很简单,就是反向建边,为什么反向建边?假设一个点的入度为2,通过邻接表是无法找到是哪条边连过来的,但是反着建边就可以,我们只需要缩点之后找到环的位置,遍历环中的每个点找到最大的编号。如果无环肯定有点入度为2,输出较大的编号即可。

/*
Work by : Dreamcatcher
Knowledge : 神仙算法
Time : O(过不了)
*/
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int INF=0x7fffffff;
const int Mod=114514;
const int N=1e6+7;

int read() {
    int x=0,f=0;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) f|=(ch=='-');
    for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch&15);
    return f?-x:x;
}

void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(x>9) print(x/10);
    putchar(x%10+48);
}

int n,Outd[N];
int head[N],cnt;struct node{int v,id,nxt;}e[N];
void Add_edge(int u,int v,int id){e[++cnt]=(node){v,id,head[u]};head[u]=cnt;}

bool vis[N];
int dfn[N],low[N],tot,t,Num[N],stc[N],sc,Size[N];
vector<int>G[N];

void tarjan(int u){
    dfn[u]=low[u]=++tot;
    stc[++sc]=u,vis[u]=true;
    for(int i=head[u];i;i=e[i].nxt){
        int v=e[i].v;
        if(!dfn[v]) tarjan(v),low[u]=min(low[u],low[v]);
        else if(vis[v]) low[u]=min(low[u],dfn[v]); 
    }
    if(low[u]==dfn[u]){
        Size[++t]++;int pre=stc[sc--];
        G[t].push_back(pre);vis[pre]=false;Num[pre]=t;
        while(pre^u){
            pre=stc[sc--];++Size[t];Num[pre]=t;
            vis[pre]=false;G[t].push_back(pre);
        }
    }
}

signed main() {
   n=read();
   for(int i=1,u,v;i<=n;i++){
       u=read();v=read();
       Add_edge(v,u,i);Outd[v]++; 
   }int pos=INF;
   for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
   for(int i=1;i<=t;i++) if(Size[i]>=2){pos=i;break;}
   if(pos^INF){int Ans=0;
       for(int i=0;i<G[pos].size();i++){int v=G[pos][i];
           if(Outd[v]==2){
               for(int j=head[v];j;j=e[j].nxt){
                   Ans=e[j].id;int vv=e[j].v;
                   if(Num[vv]==pos) return print(Ans),0;
               }
           }
           for(int j=head[v];j;j=e[j].nxt){
               int vv=e[j].v;
               if(Num[vv]^pos) continue;
               Ans=max(Ans,e[j].id);
           }
       }return print(Ans),0;
   }int Ans=0;
   for(int i=1;i<=n;i++){
       if(Outd[i]==2)
       for(int j=head[i];j;j=e[j].nxt) 
       Ans=max(e[j].id,Ans);
       return print(Ans),0;
   }
   return 0;
}


T3-给大佬递茶

毒品题,以后再说。

不拖了,再拖就三月了。设 \(f[i][j]\) 表示 \(Alice\)\(i\) 吨,\(Bob\)\(j\) 吨时的概率,又有两手结论:

  • \(1000 \le n\) 时,概率是 \(1\)
  • \(Ans(n,k)=Ans(\frac{n-1}{k}+1,1)\),也就是将 \(K\) 整成 \(1\),那个下取整。

转移方程按题目模拟即可

/*
Work by : Dreamcatcher
Knowledge : Rubbish algorithm
Time : O(Ac)
*/
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int INF=0x3f3f3f3f;
const int Mod=1e9+7;
const int N=10000;

int read() {
    int x=0,f=0;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) f|=(ch=='-');
    for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch&15);
    return f?-x:x;
}

void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(x>9) print(x/10);
    putchar(x%10+48);
}

double f[N][N],Ans=0;
int n,K;

signed main() {
   n=read();K=read();
   n=(n-1)/K+1;K=1;
   if(n>=1000) return puts("1.000000"),0;
   f[n][n]=1.0;
   for(int i=n;i>=1;i--)
   for(int j=n;j>=1;j--)
   for(int k=1;k<=4;k++)
   f[max(0,i-k)][max(0,j+k-4)]+=f[i][j]/4.0;
   for(int i=1;i<=n;i++) Ans+=f[0][i];
   Ans=Ans+f[0][0]/2.0;
   printf("%.6lf",Ans);
   return 0;
}

革命尚未成功,同志仍需努力。

posted @ 2022-02-16 11:42  Gym_nastics  阅读(31)  评论(0编辑  收藏  举报