高一普及组模拟赛3

4道题400分

赛时:150(第19)

赛后两分钟:310(第2)

贴一下成绩

是的,这显然是一个悲伤的故事

T2和T4因为数组开小了被卡了160分,啊啊啊啊啊啊啊啊

要是思考能力不行,想不到怎么做,考了第19,我只会觉得自己废物,但如果这种细节能力上出问题,只会让我觉得自己是智障

好的让我发泄一下(毕竟考的不好被winersrain嘲讽还是很气人的,哦,他好像改名rbq了)

得到一个启示:只要数组开不爆,就给爷往死里开啊啊啊啊啊啊

    你算nm的数组空间,你直接往死里开不行?你tmd算的对吗你,你就在这算,c

不过还是说一下,T4(10000+1000)*200 依据我的推算完全够,但是被卡了80分!!!!!,加个0直接A了

                             T2  (10000+1000)*26 依据玄学推算,应该大概也够,但是依旧被卡了80分c

                            T4 后来又看了,大概就是,后面那个我建了M->E级别的一个图,而我的数组只开了n的级别,没有考虑到后面新建的边,所以炸的还是挺多的

                            T2 的trie树就是玄学范围,还有一个就是我以为我开的26,其实我开的20,这里直接炸的飞起,确实,我tm少了6个字母竟然还有20分,这么一想反倒是我的不是了

 

T1 李时珍的皮肤衣

 李时珍的皮肤衣

这题也没有什么好说的,一看就感觉是个九连环(我考后讲题的时候只有Sakura表示赞同,难道他们都没有童年吗?),想到了二进制累加,大概花了20分钟时间就A了,然后去看T2 我甚至还写了一个对标快速幂

考场代码(AC代码)

查看代码
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int mx=1000;
typedef long long ll;
ll n;
ll power(ll a,ll n,ll p){
	ll ans=1;
	while(n){
		if(n&1)ans=ans*a%p;
		a=a*a%p;
		n>>=1;
	}
	return ans;
}
ll power1(ll a,ll n,ll p){
	ll ans=1;
	while(n){
		if(n&1)ans=ans*a;
		a=a*a;
		n>>=1;
	}
	return ans;
}
void Solve(){
	scanf("%lld",&n);
	ll ans=(power(2,n-1,n)+1)%n;
//	ll an=power1(2,n-1,n)+1;
	printf("%lld",ans);
}
int main(){
//	freopen("lsz.in","r",stdin);
//	freopen("lsz.out","w",stdout);
	Solve();
	return 0;
}

 

T2 马大嘴的废话

马大嘴的废话

这个一看就是trie树,但是我的trie树只练了题库的几道板子题,一时间也就没有想到怎么去处理,所以就跳了去看T3,看了T3,T4后,就,正在思考T4中,突然就会做这个题了,挺奇妙的

当然最后数组开小被卡了80分,实际得分20

AC代码

查看代码
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int mx=1000000+1000;
typedef long long ll;
//字典树 很显然,就是找的时候具体怎么操作?
//就很恶心 
//主要两个问题:
//1.db 在中间我怎么去找: 把每个串的所有子串都插进去 时间过得去,感觉可行 
//2.明显的重复怎么搞:再开一个树记录每个点的重复次数  最后加和不好搞,但也没有办法了 
     
int n,m;
char s[mx][30];
int t[mx][30],nu[mx][30],an[mx][30];
int rt,cnt;
void Insert(char s[],int st,int en,int num){
	rt=0;
//	printf("kkk  %c\n",s[st]);
	for(int i=st;i<=en;++i){
		int id=s[i]-48;
	//	printf("id=%d rt=%d\n",id,rt);
		if(t[rt][id]==0){
			t[rt][id]=++cnt;
			nu[rt][id]=num;
			an[rt][id]=1;
		}
		else if(nu[rt][id]!=num){//记得判断num 
			an[rt][id]++;
//			printf("an[%d][%d]=%d\n",rt,id,an[rt][id]);
			nu[rt][id]=num;//这个肯定递增,主要是把它换成下一个主串
			//防止同主重加 
		}
		rt=t[rt][id];
	}
}
int find(char s[]){
	int ls=strlen(s+1);
	rt=0;
	int ans=0; 
	for(int i=1;i<=ls;++i){
		int id=s[i]-48;
	//	printf("")
		if(t[rt][id]==0)return 0;//因为分出子串了,所以不行就是不行
	//	printf("kkkkkkkkkk\n");
	    ans=an[rt][id];//我可真服了你个zz,答案不就是an,你加nm呢 
	//    printf("ans=%d\n",ans);
	    //这个要在rt更新上面 
		rt=t[rt][id];	
	}
	return ans;//这个又又又忘了c 
}
void Solve(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%s",s[i]+1);
		int len=strlen(s[i]+1); 
		for(int j=1;j<=len;++j){
			//如果一条中出现多次,只算一次
			Insert(s[i],j,len,i);//num注意,同一主串中的重复是不用记录的,md真烦 
		} 
	} 
	scanf("%d",&m);
	for(int i=1;i<=m;++i){
		char ss[25];
		scanf("%s",ss+1);
		int ans=find(ss);
		printf("%d\n",ans);
	}
}
int main(){
//	freopen("mdz.in","r",stdin);
//	freopen("mdz.out","w",stdout);
	Solve();
	return 0;
}

 

T3 ssy的队列

SSY的队列

这个题一开始看受T1影响先去倒数学式子,倒了一会没倒出来又感觉是个状压DP,然后就跳了,当做完T2,T4回来的时候我将近还有一个半小时时间,当时我觉得300差不多已经rank1了,所以就有点摆,不想写了

当然后来知道这拿rank1的想法其实也挺奇妙,首先赛时rank2确实是290,300是比第二高,其次是rank1 kiritokazuto这个姐控370让我挺意外。所以剩这么长时间我就开始慢悠悠地做它,最后倒了个互斥组数为2的式子水了10分

T4 清理牛棚

清理牛棚

这个题我不知道为什么一看就有一种熟悉亲切感,就很离谱,后来考完试kiritokazuto告诉我这几道题我初中考过一次,what???!!我当时人都傻了,我是真真实实的一点印象都没有,但凡我有半点印象不至于数组开小被卡160分。

但这个题确实感觉好像做过一样。上来没想过DP,就先用二分替换,过了一会儿反应过来这替换过程不就是松弛操作,然后果断写了个spfa,立马就A了(当然数组开小了),又回去把第二题A了。后来又觉得是个DP又有点慌,但最终也没有改

这里说一下,二分替换这个地方我觉得是松弛操作就用最短路完成了某种意义上的优化,但是其实再往下想一步可以用单调栈完成这个优化DP(这个恰好是Sakura的思路),完全两个思路,但都能A。winersrain用线段树优化DP

也能做,但让我觉得最离谱的是Anastasia纯暴力DP也能A,而且我一看他那个思路就觉得哇好简单怎么我就想不到

贴一下我和Sakura的代码

我的

查看代码

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
const int mx=100000+1000;
typedef long long ll;
int n,M,E;
//好家伙,想了半天二分替换
//这二分替换的过程不就是松弛操作!!!!最短路!!!! 
//我宣布我是天才不接受反驳
//你怎么这么聪明 mua~ 
// 0 0也是一个时间我吐了 
//我莫名有点慌,DP才是正解吧,可我也没有时间改了 
struct Node{
	int from;
	int to;
	int next; 
	int data;
}e[mx*200];
int head[mx*200];
int dis[mx];
int len;
bool vis[mx];
void Insert(int u,int v,int w){
	e[++len].from=u;
	e[len].to=v;
	e[len].data=w;
	e[len].next=head[u];
	head[u]=len;
}
void spfa(int rt){
	queue <int> q;
	vis[rt]=1;
	dis[rt]=0;
	q.push(rt);
	while(q.empty()==false){
		int u=q.front();
		q.pop();
		for(int i=head[u];i;i=e[i].next){
			int v=e[i].to; 
	//		printf("u=%d v=%d\n",u,v);
			int w=e[i].data;
			if(dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				if(vis[v]==0){
					vis[v]=1;
					q.push(v);
				}
			}
		}
		vis[u]=0;
	}
}
void Solve(){
	scanf("%d%d%d",&n,&M,&E);
	E++; 
	memset(dis,0x3f,sizeof(dis));
	for(int i=1;i<=n;++i){
		int t1,t2,s;
		scanf("%d%d%d",&t1,&t2,&s);
		Insert(t1,t2+1,s);
	}
	//printf("%d\n",dis[5]);
	//起点就是M
	for(int i=M;i<=E-1;++i){
		//v=-1应该问题不大? 
		if(i==0)continue;
		Insert(i,i-1,0);//时间串联,保证跑最短路能跑下来 
		//不这么搞,2->4 3->6 你到不了6,但是实际上可以走六 
		//但是不能加E的,因为无解要-1,细节还挺多 
	} 
	spfa(M);
	if(dis[E]==1061109567){
		printf("-1\n");
	}
	else printf("%d\n",dis[E]);
}
int main(){
	freopen("clean.in","r",stdin);
	freopen("clean.out","w",stdout);
	Solve();
	return 0;
}

Sakura的

查看代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector> 
#define Sa Sakura
#define _ putchar(' ')
#define endl putchar('\n')
#define Re register int
#define int long long
using namespace std; 
inline int read()
{
	Re f=0,x=0;char c=getchar();
	while(!isdigit(c)) f|=c=='-',c=getchar();
	while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return f?-x:x;
}
inline void ot(int x)
{
	cout<<x;
}
vector<int> vec[100000],w[100000];
int n,m,e,top,sta[100000],f[100000];
signed main()
{
	freopen("clean.in","r",stdin);
	freopen("clean.out","w",stdout);
	n=read(),m=read(),e=read()-m+1;
//	ot(e),endl;
	for(Re i=1,t1,t2,s;i<=n;i++){
		t1=read()-m+1,t2=read()-m+1,s=read();
		vec[t2].push_back(t1),w[t2].push_back(s);
	//	ot(t1),_,ot(t2),endl;
	}
	if(vec[e].size()==0){
		ot(-1);
		return 0;
	}
	sta[++top]=0;
	for(Re i=1;i<=e;i++){
		f[i]=999999999999;
	//	cout<<"sta:";for(Re j=1;j<=top;j++) ot(sta[j]),_;endl;
		for(Re j=0;j<vec[i].size();j++){
			int l=1,r=top,pos=-1;
			while(l<=r){
				int mid=l+r>>1;
				if(sta[mid]+1>=vec[i][j]) pos=sta[mid],r=mid-1;
				else l=mid+1;
			}
			if(pos!=-1) f[i]=min(f[i],f[pos]+w[i][j]);
		//	ot(vec[i][j]),_,ot(i),_,ot(pos),_,ot(f[i]),endl;
		}
		if(f[i]==999999999999) continue;
		while(top&&f[sta[top]]>=f[i]) top--;
		sta[++top]=i;
	}
	if(f[e]==999999999999) ot(-1);
	else ot(f[e]);
}

显然他的码风比我的丑(不接受反驳)

总归就是这些,其他的一些繁琐细节就不再写了,也算是有得有失,得 就是让自己看到了自己能力方面还是有些欠缺,不可骄傲自满;失 就是又又又没有拿rank1好遗憾,没有那么多如果,输了就是输了

对了,还有: 智者不入爱河,青春献给祖国

posted @ 2022-05-15 11:59  SMTwy  阅读(62)  评论(7编辑  收藏  举报