23.12.3周报(重庆省赛准备阶段)

昨晚的div2算是拿下了,终于上了绿名,开心.

腐乳manjuan,出列!

把复活赛的I题补了,很好的一道题啊

题意:自行理解

思路:题意很好理解,但思路不好出,什么树状数组,dp之类的都不行。实际上这道题需要逆向思维,一个一个删除处理不了,就变为处理倒着一个一个加上去,然后用并查集维护。虽然思路网上看的,但代码实现还是我自己敲的,挺满意。

代码如下:

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using PII=pair<int,int>;

const int N=1e5+10,M=1e9+10;
int n;
int a[N],p[N];
int fa[N];
bool vi[N];
vector<ll>ve;
ll sum[N],tmp;
int fnd(int x){
	return fa[x]==x?x:fa[x]=fnd(fa[x]);
}
void solve(){
	cin >> n;
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=n;i++){
		cin >> a[i];
		sum[i]=a[i];
	}
	for(int i=1;i<=n;i++){
		cin >> p[i];
	}
	for(int i=n;i;i--){
		vi[p[i]]=1;
		if(vi[p[i]-1] && vi[p[i]+1]){
			int x=fnd(p[i]-1),y=fnd(p[i]+1);
			fa[x]=p[i],fa[y]=p[i];
			sum[p[i]]+=sum[x],sum[p[i]]+=sum[y];
			ve.push_back(max(sum[p[i]],tmp));
			tmp=max(sum[p[i]],tmp);
		}else if(vi[p[i]-1]){
			int x=fnd(p[i]-1);
			fa[x]=p[i];
			sum[p[i]]+=sum[x];
			ve.push_back(max(sum[p[i]],tmp));
			tmp=max(sum[p[i]],tmp);
		}else if(vi[p[i]+1]){
			int x=fnd(p[i]+1);
			fa[x]=p[i];
			sum[p[i]]+=sum[x];
			ve.push_back(max(sum[p[i]],tmp));
			tmp=max(sum[p[i]],tmp);
		}else{
			ve.push_back(max(sum[p[i]],tmp));
			tmp=max(sum[p[i]],tmp);
		}
	}
	for(int i=ve.size()-2;i>=0;i--) cout << ve[i] << endl;
	cout << 0;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t=1;
	//cin >> t;
	while(t--) solve();
	return 0;
}
//make it count
//开ll plz

复活赛的F题,虽然现在有点看不懂,但标记一下:

题意:从0,0点向右上射出一道光,直到被任一角落吸收,问第一次经过k个传感器的时间,如没经过,输出-1。

思路:没有思路,网上说是要用扩展欧几里得,看来确实得学习新的算法了,不然如康康所说,会遇到瓶颈。

但在这之前,让我们先来解决一道暴力

题意:自行理解

思路:暴力,想了半天不到怎么暴,搜了下发现是道1500分的题,洛谷上是黄题,倍受打击

代码如下:

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using PII=pair<int,int>;

const int N=2e5+5;
int n,m;
int a[44][44];
void swp(int x,int y){
	for(int i=1;i<=n;i++){
		swap(a[i][x],a[i][y]);
	}
}
bool check(int b[44][44]){
	for(int i=1;i<=n;i++){
		int cnt=0;
		for(int j=1;j<=m;j++){
			if(b[i][j]!=j) cnt++;
		}
		if(cnt!=0 && cnt!=2) return 0;
	}
	return 1;
}
void solve(){
	cin >> n >> m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin >> a[i][j];
		}
	}
	if(check(a)){cout << "YES"; return ;}
	for(int i=1;i<m;i++){
		for(int j=i+1;j<=m;j++){
			swp(i,j);
			if(check(a)){cout << "YES"; return ;}
			swp(i,j);
		}
	}
	cout << "NO";
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t=1;
	//cin >> t;
	while(t--) solve();
	return 0;
}
//make it count
//开ll plz

星期二:

和李,强打了场vp,22年江西省赛,打之前以为江西赛不会很难,结果。。

签到题3道做了俩,也都没有必要放上来。

标记一下E题(因为实在找不到题解,然后要用的算法还不会):

题意:将一数以数位拆解成k段(自由拆解),要求第一段和最后一段位数和的奇偶性相同,第二段和倒数第二段,以此类推,问有多少拆分方案

思路:据出题人说是区间dp+前缀和优化,我读题时也想到了可能是dp,但我不会dp啊,然后网上根本找不到这场比赛的题解,只能等以后有缘再来补。

然后看了下G题的思路,分类讨论。

星期三:

古早每日三题(trial 40)A题:

题意:自行理解

思路:一眼构造,不过不是很难的。ac后看了看网上有说欧拉回路什么的,不过不懂。

代码如下:

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using PII=pair<int,int>;

const int N=2e5+10,M=1e9+10;
const int mod=998244353;
int n,k;
int cnt;
void solve(){
	cin >> n >> k;
	while(cnt<n){
		for(int i=1;i<=k;i++){
			for(int j=i;j<=k;j++){
				cout << (char)('a'+j-1),cnt++;
				if(cnt==n) break;
				if(j!=k) cout << (char)('a'+i-1),cnt++;
				if(cnt==n) break;
			}
			if(cnt==n) break;
		}
	}
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t=1;
//	cin >> t;
	while(t--) solve();
	return 0;
}
//make it count
//开ll plz

星期四:

挂道pta的题

题意:见题面

思路:第一次存棵树,后面的输入拿来比较。他这里有个很坑的点,数组必须初始化为-1,但题面上又写的给正整数,卡我老半天时间,恶心len。

代码如下:

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using PII=pair<int,int>;

const int N=1e6+10;
int n,l;
int a[N],b[N];
bool cmp(int a[N],int b[N]){
	for(int i=1;a[i];i++){
		if(a[i]!=b[i]) return 0;
	}
	return 1;
}
void solve(){
	while(cin >> n >> l && n){
		memset(a,0,sizeof(a));
		for(int i=1;i<=n;i++){
			int tmp;
			cin >> tmp;
			int j=1;
			while(a[j]){
				if(tmp<a[j]) j*=2;
				else j=j*2+1;
			}
			a[j]=tmp;
		}
		while(l--){
			memset(b,0,sizeof(b));
			for(int i=1;i<=n;i++){
				int tmp;
				cin >> tmp;
				int j=1;
				while(b[j]){
					if(tmp<b[j]) j*=2;
					else j=j*2+1;
				}
				b[j]=tmp;
			}
			if(cmp(a,b)) cout << "Yes" << endl;
			else cout << "No" << endl;
		}
	}
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t=1;
	//cin >> t;
	while(t--) solve();
	return 0;
}
//make it count
//开ll plz

古早每日三题(同上)的B题:

算了题太长不截屏了。

题意:n条链子,找最大环。

思路:当成模拟写了俩天,wa4,然后上网一搜,贪心。。原来那代码也挺长的,懒得贴出来了。

星期五:

古早每日三题(同上)的C题:

题意:自行理解

思路:最开始当贪心模拟做,wa7,然后看网上二分,又用二分写了遍,wa7。。

结果是要当二分答案来写,代码异常简洁,如下:

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using PII=pair<int,int>;

const int N=2e5+10,M=1e9+10;
const int mod=998244353;
int n,z;
int x[N];
int ans;
bool check(int mi){
	for(int i=mi;i;i--){
		if(x[n-mi+i]-x[i]<z) return 0;
	}
	return 1;
}
void solve(){
	cin >> n >> z;
	for(int i=1;i<=n;i++) cin >> x[i];
	sort(x+1,x+n+1);
	int l=0,r=n/2;
	while(l<=r){
		int mid=l+(r-l)/2;
		if(check(mid)) ans=mid,l=mid+1;
		else r=mid-1;
	}
	cout << ans;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t=1;
//	cin >> t;
	while(t--) solve();
	return 0;
}
//make it count
//开ll plz

星期六:

为了适应下重庆赛的时间,早上9点开始vp 第四届辽宁省赛,但脑子一直动不起来,基本都是强在框框写。赛前得调整下,要是17号我还是这状态,感觉会寄。

先贴俩题,然后再看情况补几道。

B题:

题意:如题

思路:先枚举,再二分。然后四舍五入这个操作,还好我以前用过(给出表面积,求最大体积的三分题),马上操作了出来。

代码如下:

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using PII=pair<int,int>;

const int N=2e5+10,M=1e9+10;
const int mod=998244353;
int n;
double a;
bool check(int x){
	int l=1,r=x;
	while(l<=r){
		int mid=l+(r-l)/2;
		if(round(1.0*mid/x*10000)/100>a) r=mid-1;
		else if(round(1.0*mid/x*10000)/100<a) l=mid+1;
		else return 1;
	}
	return 0;
}
void solve(){
	cin >> a;
	for(int i=1;i<=10000;i++) if(check(i)){cout << i; return ;}
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t=1;
//	cin >> t;
	while(t--) solve();
	return 0;
}
//make it count
//开ll plz

开始补题环节:

L题:

题意:见题

思路:朴素算法可以跑到1e15,一眼数据结构题,但不会。

补算法的话有点难,好像要用莫队+树状数组。

又学了遍dij最短路算法。

周日:

8点20开始vp 21年山东省赛,全程汗流浃背ac了3道题,先贴道签到题。

题意:给n个数,输出其平均数至小数点后k位(n,k可达1e5)

思路:1e5的精度,double再怎么long都得寄,得边算边输出,可能是高精度的知识,但没学过不影响签到。(ps.299队17队爆0)

代码如下:

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using PII=pair<int,int>;

const int N=1e5+10;
int n,k;
int a;
void solve(){
	cin >> n >> k;
	for(int i=1;i<=n;i++){
		int tmp;
		cin >> tmp;
		a+=tmp;
	}
	cout << a/n << '.';
	a%=n;
	while(k--){
		a*=10;
		cout << a/n;
		a%=n;
	}
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t=1;
//	cin >> t;
	while(t--) solve();
	return 0;
}
//make it count
//开ll plz

 补M题:

题意:构造,构造了近四个小时没构出来,看完题解又觉得不应该,还是构造题做少了。

思路:c为1,都为1。a最左列为1,最右列为0,b反之。a奇数行为1,偶数行为0,b反之。

代码如下:

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using PII=pair<int,int>;

const int N=1e6+10;
int n,m;
char c[550][550];
void solve(){
	cin >> n >> m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin >> c[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(j==1) cout << 1;
			else if(j==m) cout << 0;
			else if(c[i][j]=='1') cout << 1;
			else if(i&1) cout << 1;
			else cout << 0;
		}
		cout << endl;
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(j==m) cout << 1;
			else if(j==1) cout << 0;
			else if(c[i][j]=='1') cout << 1;
			else if(i&1) cout << 0;
			else cout << 1;
		}
		cout << endl;
	}
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t=1;
	//cin >> t;
	while(t--) solve();
	return 0;
}
//make it count
//开ll plz

补c题:

题意:树上点可为白色或黑色,黑点子树节点必须全为黑。给一k为染色方案,要求输出一颗刚好k种染色方案的树。

思路:3号没补上这题,看下周的吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值