首页 > 其他分享 >Codeforces Round 918 (Div. 4)

Codeforces Round 918 (Div. 4)

时间:2024-04-02 20:00:29浏览次数:175  
标签:p2 int auto Codeforces 918 push Div dis ls

Codeforces Round 918 (Div. 4)

D:本题从实现上来说正难则反,应该倒着做

在我正着做的时候,由于在访问后面元素的时候没有判边界,导致数组越界,出现奇怪字符在最后答案中。

int n, m;
int a[N];
bool check(char c){
	if(c=='a'||c=='e')return true;
	else return false;
}
void solve(){
	cin>>n;
	string s;cin>>s;
	string ans;
	string tmp=".";
	for(int i=0;i<n;){
		//cerr<<i<<" ";
	
		if(check(s[i])==0){
			if(i)ans+=tmp;
			ans+=s[i];ans+=s[i+1];
			if(check(s[i+2])==0){
				if(check(s[i+3])){
					i+=2;
				}
				else {
					//if(i+2>=n)
					if(i+2<n)ans+=s[i+2];
					i+=3;
				///	cerr<<ans<<endl;
				}
			}
			else {
				i+=2;
			}
		}
		//cerr<<i<<endl;
		//ans+=tmp;
	}
	//cerr<<ans.size();
	cout<<ans<<endl;
}

E题:给定数组,问是否存在一段连续子数组满足奇数项的和等于偶数项。

Solution1:我们可以不去考虑奇偶性,而去考虑前缀和.-我们令原数组偶数项全部变为相反数,如果出现前缀和之前出现过或者为0,则存在
Solution2:对奇数位置和偶数位置做前缀和,分别记作p1,p2。

限制条件变成\(p1[R]-p1[L-1]==p2[R]-p2[L-1]\)

交换位置,\(p2[L-1]-p1[L-1]==p2[R]-p1[R]\)

把所有位置的 {奇偶前缀和之差,位置} 存入set 枚举L,在set里面二分找合法的R即可

void solve(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	set<int>s;
	int sum=0;
	s.insert(0LL);
	for(int i=1;i<=n;i++){
		if(i%2){
			sum+=a[i];
			
		}
		else {
			sum-=a[i];
			
		}
		if(s.count(sum)){
			cout<<"YES"<<endl;
		return ;
		}
		else s.insert(sum);
	}
	cout<<"NO"<<endl;
}

F:需要找到起点在自己后面,但是终点在自己前面的人的数量

Solution:对起点排序,省去一维,只看终点在自己前面的人,按照上述方式,我们需要倒着遍历。实现上由于值域很大,我们需要保序离散化。对于每个人的贡献由于需要动态加点和区间和查询,使用树状数组维护。
//每次要找到在排序后的a[i]的后面并且第二维小于b[i]的数需要,需要动态添加
//不能提前排序无法区分,使用树状数组
 
void solve(){
	// cin>>n;
	// vector<int>v;
	// for(int i=1;i<=n;i++){
		// int x,y;cin>>x>>y;
		// a[i]={x,y};
		// v.push_back(y);
	// }
	// sort(v.begin(),v.end());
	// for(auto x:v)cerr<<x<<" ";
	// cerr<<endl;
	// sort(a+1,a+1+n);
	// int ans=0;
	// //题目保证不重复
	// for(int i=1;i<=n;i++){
		// int val=a[i].second;
	// int pos=lower_bound(v.begin(),v.end(),val)-v.begin()+1;
		// ans+=pos-i;
		// cerr<<a[i].first<<" ";
		// cerr<<val<<" "<<pos-1<<endl;
	// }
	// cout<<ans<<endl;
	cin>>n;
	vector<int>ls;
	//这里需要有序离散化
	
	
	Fenwick<int>c(n+1);
	for(int i=1;i<=n;i++){
		int x,y;
		cin>>x>>y;
	ls.push_back(y);
		a[i]={x,y};
		
	}
	sort(ls.begin(),ls.end());
	auto id=[&](int x){
	int pos=lower_bound(ls.begin(),ls.end(),x)-ls.begin()+1;
		return pos;
	};
	
//每个数关注比自己起点大的数的终点是不是比自己小
	sort(a+1,a+1+n);
	int ans=0;
	for(int i=n;i>=1;i--){
		auto [x,y]=a[i];
		y=id(y);
		ans+=c.sum(y);
		c.add(y,1);
	}
	cout<<ans<<endl;
}

G:求从1-n的最短路,特别的是加入自行车限制,在每个点可以选择使用当前点的自行车,或者继续使用自己之前的自己车,不同车对边权影响。

Solution:从思想上来说可以从分层图上理解,多加一维实现自行车的转移。也有人说就是二维dijstra,因为算法的正确性保证是在此基础上。对于当前每个点我们可以选择换城市不换自行车,或者换车不换城市(只能一次)
int n, m;
int a[N];
//dij加一维状态表示自行车信息
struct edge{int v,w;};
vector<edge>e[N];
void solve(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)e[i].clear();
	vector<int>s(n+1);
	for(int i=1;i<=m;i++){
		int u,v,w;cin>>u>>v>>w;
		e[u].push_back({v,w});
		e[v].push_back({u,w});
	}
 for(int i=1;i<=n;i++)cin>>s[i];
 priority_queue<a3, vector<a3>, greater<a3>>q; 
 vector<vector<int>>dis(n+1,vector<int>(n+1,1e18));
 vector<vector<bool>>vis(n+1,vector<bool>(n+1,0));
 q.push({0,1,1});
 dis[1][1]=0;
 while(q.size()){
 	auto [d,u,b]=q.top();q.pop();
 	if(vis[u][b]==true)continue;
 	vis[u][b]=true;
 	
 	
 	
 		for(auto [v,w]:e[u]){
 			if(dis[v][b]>d+w*s[b]){
 				dis[v][b]=d+w*s[b];
 				q.push({dis[v][b],v,b});
 			}
 		}
 		if(b!=u){
 		q.push({d,u,u});
 		dis[u][u]=d;
 		}
 	}
 
cout << *min_element(dis[n].begin() + 1, dis[n].begin() + n);
cout<<endl;

}

标签:p2,int,auto,Codeforces,918,push,Div,dis,ls
From: https://www.cnblogs.com/mathiter/p/18111391

相关文章

  • 状压dp板子(cf div4 #937)
    #include<bits/stdc++.h>usingnamespacestd;intn;vector<int>v[20];stringa[20],b[20];booldp[500010][20];voiddfs(ints,intnow){dp[s][now]=true;for(autonxt:v[now]){if(s&(1<<nxt))continue;......
  • WolfInZooDivOne
    dp#预处理\(dp_{i,j}\)表示第\(i\)个选择,\(i\)前面的第一个为\(j\)的方案数预处理不合法的区间,暴力转移//Author:xiaruize#ifndefONLINE_JUDGEboolstart_of_memory_use;#endif#include<bits/stdc++.h>usingnamespacestd;#ifndefONLINE_JUDGEclock_tstar......
  • 【题解】Codeforces 1942E - Farm Game
    题目链接:https://codeforces.com/contest/1942/problem/E题目大意:输入一个\(l\)和一个\(n\),其中\((1\leql\leq10^6,2n<=l)\),表示有\(l\)个不同的空位(分别是\([1,l]\))和\(2n\)头完全一样的牛。Alice和Bob分别有\(n\)头牛,并且他们的牛是间隔排列的。每一次......
  • CodeTON Round 8 (Div. 1 + Div. 2)
    ProblemA显然\(k=1,n\)时才有解。ProblemB倒序扫一遍即可。ProblemC1(2)C1直接相邻为\(1\)的能用,否则不算。C2就是把间隔挖出来,奇偶分别选择。ProblemD直接记录每个状态的\(k\)优解,然后堆转移。ProblemE假设两种牛之间的间隔大小分别为\(g_i\)。首先......
  • CodeTON Round 8 (Div. 1 + Div. 2, Rated, Prizes!)做题笔记
    A.FarmerJohn'sChallengeProblem-A-Codeforces题意:构造出满足条件的数组a,否则输出-1做法:判断k和n或者1的关系;k==1则输出1就行,k==n就从1输出到n;都不满足就输出-1;代码:#include<iostream>usingnamespacestd;intmain(){intt;cin>>t;while(t--){intn,k;cin......
  • cf(div4) 第四周
    Problem-E-CodeforcesE.NearlyShortestRepeatingSubstring题解:我们直接枚举长度题目限制很多首先,枚举长度要确保整除然后我们在取从头开始的这个长度的字符串一一向下比对这里我们还要去这个长度的i+=len下一个字串在一一去比对然后就不可能往下取了,如果向下取那就......
  • SMU Winter 2024 div2 ptlks的周报Week 7(3.25-3.31)
    哈夫曼编码对出现频率大的字符赋予较短的编码,对出现频率小的字符赋予较长的编码。哈夫曼树的建树过程为,每次选取最小和次小的根节点,将它们之和作为它们的根节点,左子节点为小点,右子节点为次小点,直至仅剩一棵树。一棵哈夫曼树,左子树为0,右子树为1,以根节点到叶子结点的路径作为每个叶......
  • CodeTON Round 8 (Div. 1 + Div. 2, Rated, Prizes!) D
    链接开始的时候看错题了。以为区间是可以我划分的,后面才发现是连着的区域是被强制合并的。导致我第一个写了给k短路。紫砂了。然后我的第二个思路是,从后往前和从前往后做两边dp,然后尝试枚举断点,看看有没有比最优稍微劣一点的解法。然后样例就是反例。正解是想到过的,但是因为......
  • codeforces div4 Double Strings
    #include<iostream>#include<algorithm>#include<cstring>#include<map>usingnamespacestd;intT,n;strings[900005];map<string,int>mm;//存放每一个字符串是否出现过intmain(){ cin>>T; while(T--){ mm.clear();//每次清空mm里面的数......
  • Codeforces Round 937 (Div. 4)----->E. Nearly Shortest Repeating Substring
    一,思路:1.这题很容易想到枚举n的因数(时间复杂度n^(1/2)),然后根据这个长度枚举字符串,看是否满足最多只有一个不相同(时间复杂度n)。总的时间复杂度是(n根号n)的级别。又n是1e5级别所以可以过。但是当n是1e6就不行了。2.难点在于如何判断,一个字符串的不同字符数量,主要是hshah......