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;
}
革命尚未成功,同志仍需努力。