2022.5.15———HZOI【高一普及组模拟赛3】睡觉记

成绩综述

 

 

 

俺又崩咧。。。倒第五、、

kkksc03(kiritokazuto) dalao%%%

T1 李时珍的皮肤衣

我懒到懒得粘题面了

这个题主要就是推规律,主要是推出来那种*2-1(我刚开始的做法,也是爆20的做法)不是不对,是不好,因为没法快速幂

Code:

T1
#include<bits/stdc++.h>
#define char_phi signed
#define ll long long
#define re register int
#define mem(x,y) memset(x,y,sizeof(x))
#define SLEEP printf("💤")
#define SLEEPER printf("(~﹃~)~zZ")
#define MARK printf("###")
#define _MARK printf("@@@")
#define LMARK printf("$$$$$$")
#define iwh printf("我永远爱文虎")
#define _ putchar(' ')
#define endl putchar('\n')
#define ot(x) printf("%lld",x)
#define N 10000000002
using namespace std;
ll n,final_ans = 2;
inline ll read(){
    ll x = 0;char c;
    while(!isdigit(c = getchar()));
    do{
        x = (x << 3) + (x << 1) + (c & 15);
    }while(isdigit(c = getchar()));
    return x;
}
ll ksm(ll a,ll b){
	ll res = 1;
	while(b){
		if(b & 1) res = (res * a) % n;
		b >>= 1;
		a = (a * a) % n;
	}
	return (res % n);
}
void work(){
    // //上一次的结果 << 1 - 1
    // //然而取模怎整?朴素取模???好像分配律不大管用了。。
    // n = read();
    // if(n == 1){
    //     putchar('0');
    //     exit(0);
    // }
    // if(n == 2){
    //     putchar('1');
    //     exit(0);
    // }
    // final_ans = 3;//达到第二层
    // for(int i = 2 ; i <= n-1 ; ++ i){//会爆吧,,
    //     final_ans <<= 1,final_ans -= 1;
    //     // ot(final_ans),_;
    // }
    // // endl;
    // final_ans %= n;
    // // ot(final_ans);
    // printf("%lld",final_ans);
    n = read();
    // final_ans = pow(2,n-1);
    // final_ans += 1;
    printf("%lld",((ksm(2,n-1) + 1) % n));
}
char_phi main(){
    freopen("lsz.in","r",stdin);
    freopen("lsz.out","w",stdout);
    work();
    return 0;
}
/*#include<bits/stdc++.h>
#define char_phi signed
#define ll long long
#define re register int
#define mem(x,y) memset(x,y,sizeof(x))
#define SLEEP printf("💤")
#define SLEEPER printf("(~﹃~)~zZ")
#define MARK printf("###")
#define _MARK printf("@@@")
#define LMARK printf("$$$$$$")
#define iwh printf("我永远爱文虎")
#define _ putchar(' ')
#define endl putchar('\n')
#define ot(x) printf("%lld",x)
#define N 10000000002
using namespace std;
ll n,final_ans;
inline ll read(){
    ll x = 0;char c;
    while(!isdigit(c = getchar()));
    do{
        x = (x << 3) + (x << 1) + (c & 15);
    }while(isdigit(c = getchar()));
    return x;
}
void work(){
    //上一次的结果 << 1 - 1
    //然而取模怎整?朴素取模???好像分配律不大管用了。。
    n = read();
    if(n == 1){
        putchar('0');
        exit(0);
    }
    if(n == 2){
        putchar('1');
        exit(0);
    }
    final_ans = 3;//达到第二层
    for(int i = 2 ; i <= n-1 ; ++ i){//会爆吧,,
        final_ans <<= 1,final_ans -= 1;
        // ot(final_ans),_;
    }
    // endl;
    final_ans %= n;
    // ot(final_ans);
    printf("%lld",final_ans);
}
char_phi main(){
    freopen("lsz.in","r",stdin);
    freopen("lsz.out","w",stdout);
    work();
    return 0;
}*/

T2 马大嘴的废话

这个应该是AC自动机或者trie树啥的,但是第一个没学第二个懒也不会,所以我改的时候就用了@hxqasd  (dbx)dalao的暴力

暴力把输入串拆分成字串,然后用map映射一下,注意去重(题目要求,看样例也能发现)(ajksa两个a就是重的),然后询问的时候O(1)查询

Code:

T2
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
#include <map>
#define char_phi signed
#define ll long long
#define re register int
#define mem(x,y) memset(x,y,sizeof(x))
#define SLEEP printf("??")
#define SLEEPER printf("(~﹃~)~zZ")
#define MARK printf("###")
#define _MARK printf("@@@")
#define LMARK printf("$$$$$$")
#define iwh printf("我永远爱文虎")
#define _ putchar(' ')
#define endl putchar('\n')
#define ot(x) printf("%d",x)
using namespace std;
int n,Q;
map<string,int> a;
map<string,bool>vis;
inline int read(){
    int x = 0;char c;
    while(!isdigit(c = getchar()));
    do{
        x = (x << 3) + (x << 1) + (c & 15);
    }while(isdigit(c = getchar()));
    return x;
}
void work(){//dbx_dalao的map暴力 
	n = read();
	char s[25];
	for(re i = 1,len ; i <= n ; ++ i){
		scanf("%s",s+1);
		len = strlen(s+1);
		vis.clear();
		for(re j = 1 ; j <= len ; ++ j){//暴力枚举每一个字串 
			string ss;
			for(re k = j ; k <= len ; ++ k){
				ss += s[k];
				if(vis[ss] == false){
					vis[ss] = true,++ a[ss];
				}
			}
		}
	}
	Q = read();
	while(Q --){
		scanf("%s",s);
		printf("%d\n",a[s]);
	}
}
char_phi main(){
    freopen("mdz.in","r",stdin);
    freopen("mdz.out","w",stdout);
    work();
    return 0;
}

T3 SSY的队列

%%%%%%kiritokazuto【cjh】dalao赛时拿掉T3的70pts成为赛时T3最高分(这位真的真的tql)

 

 

%%%ing(wonder)【lhd】dalao赛后首个且1A切掉

%%%caorong【cr】dallao赛后第二个且1A切掉并且拿掉最优解

//第一次改的时候caorong_dalaoT了应该是忘了写freopen

 

这题应该是压轴题了

这个思路要解释的话挺难描述的,应该是把身高们都%m分成组,然后乱搞,没法描述看我代码注释吧,实在觉得ex可以致电这位【dalao】,也就是赛时Rank1&&赛时T3拿70pts的那位大佬,他喜欢摸鱼应该回复得挺快

然后记得开long long,不开应该是被WA成40分

Code:

T3
#include<bits/stdc++.h>
#define char_phi signed
#define ll long long
#define re register int
#define mem(x,y) memset(x,y,sizeof(x))
#define SLEEP printf("??")
#define SLEEPER printf("(~﹃~)~zZ")
#define MARK printf("###")
#define _MARK printf("@@@")
#define LMARK printf("$$$$$$")
#define iwh printf("我永远爱文虎")
#define _ putchar(' ')
#define endl putchar('\n')
#define ot(x) printf("%lld",x)
#define MAX(x,y) ((x > y) ? (x) : (y))
#define MIN(x,y) ((x < y) ? (x) : (y))
#define P 1234567891
#define N 35
#define M 1005
#define base 233
using namespace std;
ll n,m,hash_R = -114514,xi_cnt,spc,final_ans = 1;
bool vis[N];
ll hi[N],cnt[N],rest_num[N];//模数为i的数有几个 
ll jc[N << 1];
map<ll,ll> mp[N];
inline ll read(){
    ll x = 0;char c;bool f = false;
    while(!isdigit(c = getchar())){
        if(c == '-'){
            c = getchar(),f = true;
            break;
        }
    }
    do{
        x = (x << 3) + (x << 1) + (c & 15);
    }while(isdigit(c = getchar()));
    if(f == true) return -x;
    return x;
}
void firster(){
	jc[0] = jc[1] = 1;
	for(re i = 2 ; i <= n+3 ; ++ i){
		jc[i] = (jc[i-1] * i) % P;
	}
	final_ans *= jc[spc],final_ans %= P;
	for(re i = 1 ; i <= n ; ++ i){//先把类按照{1,2,3..}这种顺序排一边计算答案,一会计算{2,1,3... }这种的 
		final_ans = (final_ans * jc[cnt[i]]) % P;
	}
}
ll dfs(ll nd,ll lst){//该放第几个数,上一次放的哪一类 
	//一个数一个数地放 
	if(nd > n) return 1;//累乘,返回1
	mem(rest_num,0);
	for(re i = 1 ; i <= cnt[0] ; ++ i){//spc一会单独处理 
		if(i != lst) ++ rest_num[cnt[i]];//某类有某个数量,按照这个数量再统计一次 
	}//这个是为了一会计算哈希值 
	ll haocore = spc;//Sigma (Haocore Mix) ~Regret of Yellow Tulip~
	for(re i = 1 ; i <= hash_R ; ++ i){//循环人数 
		haocore = haocore * base + rest_num[i];
	}
	(lst == 0) ? (haocore *= base) : (haocore = haocore * base + cnt[lst]);
	map<ll,ll>::iterator it = mp[nd].find(haocore);
	if(it != mp[nd].end()){//之前有过后面的那种状态【记忆化搜索】 
		return mp[nd][haocore];
	}
	ll res = 0;
	if(spc > 0){
		-- spc;
		res = dfs(nd+1,0) % P;
		++ spc;
	}
	for(re i = 1 ; i <= cnt[0] ; ++ i){//循环每一类(剩余系) 
		if(i != lst && cnt[i] > 0){
			-- cnt[i];
			res = (res + dfs(nd+1,i)) % P;
			++ cnt[i];
		}
	}
	mp[nd][haocore] = res;
	return res;
}
void work(){
	//说离来就启普发生器,一个比较奇怪的现象是这个题竟是记忆化搜索
	//感谢cjh_kiritokazuto_kkksc03_dalao的耐心讲解,%%%%%% 
	n = read();
	for(re i = 1 ; i <= n ; ++ i){
		hi[i] = read();
	}
	m = read();
	for(re i = 1 ; i <= n ; ++ i){//对身高分类 
		hi[i] %= m;
		if(hi[i] < 0) hi[i] += m;//处理负数 
	}
	for(re i = 1 ; i <= n ; ++ i){
		if(vis[i] == false){
			ll xinum = 1;
			vis[i] = true;
			for(re j = i+1 ; j <= n ; ++ j){//只用往后找 如果前面还有和j模数一样的就应该已经被标记过了,进不了循环 
				if(hi[j] == hi[i]){
					vis[j] = true,++ xinum;
				}
			}
			(xinum == 1) ? (++ spc) : (cnt[++ cnt[0]] = xinum);//所有身高中模数为i的只有一个,单独存起来,目的是降时间复杂度【深搜用】
			hash_R = MAX(hash_R,xinum);//哈希的右边界不能太大也不能太小,用系们中含有的个数最多的来定夺 
		}
	}
	firster();
	ot( ((final_ans * dfs(1,0)) % P) );
}
char_phi main(){
	freopen("ssy.in","r",stdin);
	freopen("ssy.out","w",stdout);
    work();
    return 0;
}

T4 清理牛棚

据我所知有四种做法,【单调栈优化,朴素线性dp,线段树优化dp,最短路】

我就写最短路了,把时间抽象成点,把输入的连边,然后就是一个裸的最短路了

需要注意的是{1 -> 4 , 2 -> 5}这种最短路1是到不了5的,所以把每个点之间再连一条边权为0的点既不影响答案也解决了这个问题

太妙了

T4

#include<bits/stdc++.h>
#define char_phi signed
#define ll long long
#define re register int
#define mem(x,y) memset(x,y,sizeof(x))
#define SLEEP printf("??")
#define SLEEPER printf("(~﹃~)~zZ")
#define MARK printf("###")
#define _MARK printf("@@@")
#define LMARK printf("$$$$$$")
#define iwh printf("我永远爱文虎")
#define _ putchar(' ')
#define endl putchar('\n')
#define ot(x) printf("%d",x)
#define MAX(x,y) ((x > y) ? (x) : (y))
#define MIN(x,y) ((x < y) ? (x) : (y))
#define N 100005
using namespace std;
int n,M,E,star_cnt;
bool vis[N << 1];
int head[N << 2],dis[N << 1];
struct star{
	int v,nxt;
	ll w;
}e[N << 2];//因为多连边了,我害怕,所以*4 
struct node{
	int id,d;
	node(int idd = 0,int dd = 0) {
		id = idd,d = dd;
	}
	bool operator < (const node& A) const{
		return d > A.d;
	}
};
priority_queue<node> q;
inline int read(){
    int x = 0;char c;
    while(!isdigit(c = getchar()));
    do{
        x = (x << 3) + (x << 1) + (c & 15);
    }while(isdigit(c = getchar()));
    return x;
}
inline void star_add(int u,int v,int w){
	e[++ star_cnt].v = v,e[star_cnt].w = w,e[star_cnt].nxt = head[u],head[u] = star_cnt;
}
void dij(int M){
	mem(dis,0x3f);
	dis[M] = 0,q.push(node(M,0));
	while(q.empty() == false){
		node now = q.top();
		q.pop();
		if(vis[now.id] == true) continue;
		vis[now.id] = true;
		for(re i = head[now.id] ; i ; i = e[i].nxt){
			if(dis[e[i].v] > (dis[now.id]+e[i].w)){
				dis[e[i].v] = dis[now.id] + e[i].w;
				q.push(node(e[i].v,dis[e[i].v]));
			}
		}
	}
}
void work(){
	n = read(),M = read(),E = read();
	for(re i = 1,t1,t2,s ; i <= n ; ++ i){
		t1 = read(),t2 = read(),s = read(),++ t2;
		star_add(t1,t2,s);
	}
	for(re i = M ; i < E ; ++ i){
		star_add(i+1,i,0);//{1 -> 4 , 2 -> 5}1跑不到5,所以要想办法把他俩连起来 
		//随便连就行了,只不过这样连的还少点,又周全 
		//因为连的单向边,之前t1 -> t2,这里为了能让t2指回去应该反着连 
	}
	dij(M); 
	if(dis[E+1] >= 11451419){//这个度一定把握好 
		puts("-1") ;
		exit(0);
	}
	printf("%d",dis[E+1]);
}
char_phi main(){
	freopen("clean.in","r",stdin);
	freopen("clean.out","w",stdout);
	work();
	return 0;
}
posted @   char_phi  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示