• Codeforces Round #786 (Div. 3) 补题记录


    小结:

    A,B,F 切,C 没写 1ll 对照样例才发现,E,G 对照样例过,D 对照样例+看了其他人代码(主要急于看后面的题,能调出来的但偷懒了。


    CF1674A Number Transformation

    考虑若 y 不能整除 x 则无解,否则一定存在一组解 a=1,b=y÷x

    #include
    #define IOS ios::sync_with_stdio(false)
    #define TIE cin.tie(0),cout.tie(0);
    #define int long long
    using namespace std;
    int T,n,a[200005],x,y ;
    string s;
    void solve(){
    	cin>>x>>y;
    	if(y%x){
    		cout<<"0 0"<		return ;
    	}
    	int tmp=y/x;
    	cout<<1<<' '<}
    signed main(){
    	IOS;TIE;
    	T=1;
    	cin>>T;
    	while(T--) solve();
    	return 0;
    }
    

    CF1674B Dictionary

    直接用 map 映射,用两个字符或字符串对应数字,注意两个字符相同的要跳过。

    #include
    #define IOS ios::sync_with_stdio(false)
    #define TIE cin.tie(0),cout.tie(0);
    #define int long long
    #define mk(x,y) make_pair(x,y)
    using namespace std;
    int T,n,a[200005],x,y,tot;
    string s;
    mapchar,char>,int> mp;
    void solve(){
    	cin>>s;
    	cout<mk(s[0],s[1])]<}
    signed main(){
    	IOS;TIE;
    	T=1;
    	for(char i='a';i<='z';i++){
    		for(char j='a';j<='z';j++){
    			if(i==j) continue;
    			mp[mk(i,j)]=++tot;
    		}
    	}
    	cin>>T;
    	while(T--) solve();
    	return 0;
    }

    CF1674C Infinite Replacement

    分类讨论:

    • 若替换串中有 a,且替换串长度 >1,则可以无限替换,输出 1
    • 若替换串中有 a,且替换串长度 =1,则只有一种情况,即原串
    • 否则,考虑原串中每一位是否替换,可能情况有 2 种情况
    #include
    #define IOS ios::sync_with_stdio(false)
    #define TIE cin.tie(0),cout.tie(0);
    #define int long long
    #define mk(x,y) make_pair(x,y)
    using namespace std;
    int T;
    string s,t;
    void solve(){
    	cin>>s>>t;
    	bool fl=0;
    	for(int i=0;isize();i++){
    		if(t[i]=='a') fl=1;
    	}
    	if(fl&&t.size()>1){
    		cout<<-1<		return ;
    	}
    	if(fl){
    		cout<<1<		return ;
    	}
    	cout<<(1ll<size())<}
    signed main(){
    	IOS;TIE;
    	cin>>T;
    	while(T--) solve();
    	return 0;
    }

    CF1674D A-B-C Sort

    容易发现这样操作之后只可以改变相邻两个数的位置,若原长度为奇数则第一个数会多出来,否则看两两是否相等即可。

    #include
    #define IOS ios::sync_with_stdio(false)
    #define TIE cin.tie(0),cout.tie(0);
    #define int long long
    #define mk(x,y) make_pair(x,y)
    using namespace std;
    int T,n,a[200005],b[200005];
    int l[1000005],r[1000005];
    void solve(){
    	cin>>n;
    	for(int i=1;i<=n;i++) cin>>a[i],b[i]=a[i];
    	sort(b+1,b+n+1);
    	if(n%2){
    		if(a[0]!=b[0]){
    			cout<<"NO"<			return ;
    		}
    	}
    	for(int i=1+(n%2);i<=n;i+=2){
    		if(!(a[i]==b[i]&&a[i+1]==b[i+1]||a[i]==b[i+1]&&a[i+1]==b[i])){
    			cout<<"NO"<			return ;
    		}
    	}
    	cout<<"YES"<}
    signed main(){
    	IOS;TIE;
    	cin>>T;
    	while(T--) solve();
    	return 0;
    }

    CF1674E Breaking the Wall

    分类讨论:

    1. 取原串中最小的两个数 x,y(不一定相邻),使它们变零。分别一直 2,代价为 x2+y2
    2. 取原串中相邻两个数 ai,ai+1,使他们变零。设 x 为较大数,y 为较小数:
      1. x>y×2,则一直在 x2,代价为 y+x2×y2
      2. 否则,看大小灵活 2,代价为 x+y3
    3. 取原串中间隔一数的两个数 ai,ai+2,使他们变零。设 x 为较大数,y 为较小数。先一直使中间数 2 直到 x,y 中任意一个变 0,随后剩下的一直 2,代价为 y+xy2

    去三种情况的最小答案即可。

    #include
    #define IOS ios::sync_with_stdio(false)
    #define TIE cin.tie(0),cout.tie(0);
    #define int long long
    #define mk(x,y) make_pair(x,y)
    using namespace std;
    int T,n,a[200005],ans=1e18,mn,semn;
    void case0(){
    	mn=semn=1e18;
    	for(int i=1;i<=n;i++){
    		if(a[i]		else if(a[i]	}
    	ans=min(ans,(int)ceil(mn/2.0)+(int)ceil(semn/2.0));
    }
    void case1(){
    	for(int i=1;i		int x=a[i],y=a[i+1];
    		if(xswap(x,y);
    		if(y*2min(ans,y+(int)ceil((x-y*2)/2.0));
    		else ans=min(ans,(int)ceil((x+y)/3.0));
    	}
    }
    void case2(){
    	for(int i=1;i-1;i++){
    		int x=a[i],y=a[i+2];
    		ans=min(ans,min(x,y)+(int)ceil(abs(x-y)/2.0));
    	}
    }
    void solve(){
    	cin>>n;
    	for(int i=1;i<=n;i++) cin>>a[i];
    	case0();case1();case2();
    	cout<}
    signed main(){
    	IOS;TIE;
    	T=1;
    	while(T--) solve();
    	return 0;
    }

    CF1674F Desktop Rearrangement

    题意实为要求将所有 * 移动到这种状态:

    image

    即优先填满靠左的列。

    所以每次要做的就是统计出当前棋盘上有多少 *,这是左侧该有 * 的数量,然后算出该有 * 的位置有多少是空的,即为最小移动步数。

    考虑对于每一列维护前缀和,每次更新一个点加一列,询问只要从左往右扫即可。

    #include
    #define IOS ios::sync_with_stdio(false)
    #define TIE cin.tie(0),cout.tie(0);
    #define int long long
    #define mk(x,y) make_pair(x,y)
    using namespace std;
    int T,n,m,x,y,q,s[1005][1005],sum;
    bool a[1005][1005];
    char c;
    void solve(){
    	cin>>n>>m>>q;
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++){
    			cin>>c;
    			if(c=='*') a[i][j]=1,sum++;
    		}
    	}
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++) s[i][j]=s[i-1][j]+a[i][j];
    	}
    	while(q--){
    		cin>>x>>y;
    		if(a[x][y]){
    			sum--;
    			for(int i=x;i<=n;i++) s[i][y]--;
    		}
    		else{
    			sum++;
    			for(int i=x;i<=n;i++) s[i][y]++;
    		}
    		a[x][y]^=1;
    		int tmp=sum,ans=0;
    		for(int j=1;j<=m;j++){
    			if(tmp>n) tmp-=n,ans+=n-s[n][j];
    			else{
    				ans+=tmp-s[tmp][j];
    				break;
    			}
    		}
    		cout<	}
    }
    signed main(){
    	IOS;TIE;
    	T=1;
    	while(T--) solve();
    	return 0;
    }

    CF1674G Remove Directed Edges

    首先手玩样例,可以发现一个性质:删边之后若可以从 uv,则需满足 u 的出度 >1v 的入度 >1

    同时,DAG 中要取一个点集,使可以从其中一点走向另一点,则此点集一定可以构成一条链。具体可以根据拓扑序来理解。

    所以,就可以用拓扑排序求最长路的方法来做这道题。不同的是,有入度、出度 >1 的限制条件。具体处理方法是:记下每一个点的原始入度 Ini ,如果当前队首出度 <2,则按照常规拓扑排序的来搞,否则,若走向点的原始入度 >1,则可以更新那个点的答案。同时,减入度和入队还是和一般拓排序一样。

    #include
    #define IOS ios::sync_with_stdio(false)
    #define TIE cin.tie(0),cout.tie(0);
    #define int long long
    #define mk(x,y) make_pair(x,y)
    using namespace std;
    int T,n,m,in[200005],In[200005],out[200005],f[200005],u,v,ans;
    bool vis[200005];
    vector<int> a[200005]; 
    queue<int> q;
    void solve(){
    	cin>>n>>m;
    	for(int i=1;i<=m;i++){
    		cin>>u>>v;
    		a[u].push_back(v);
    		in[v]++,In[v]++,out[u]++;
    	}
    	for(int i=1;i<=n;i++) if(!in[i]) vis[i]=1,q.push(i);
    	for(int i=1;i<=n;i++) f[i]=1;
    	while(q.size()){
    		int k=q.front();q.pop();
    		if(out[k]<2){
    			for(int i=0;isize();i++){
    				int tmp=a[k][i];
    				if(!--in[tmp]) q.push(tmp);
    			}
    			continue;
    		}
    		for(int i=0;isize();i++){
    			int tmp=a[k][i];
    			if(In[tmp]>1) f[tmp]=max(f[tmp],f[k]+1);
    			if(!--in[tmp]) q.push(tmp);
    		}
    	}
    	for(int i=1;i<=n;i++) ans=max(ans,f[i]);
    	cout<}
    signed main(){
    	IOS;TIE;
    	T=1;
    	while(T--) solve();
    	return 0;
    }

    G L & H F !


    __EOF__

  • 本文作者: Binary_1110011_
  • 本文链接: https://www.cnblogs.com/binary1110011/p/16886299.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    C++ lambda表达式
    js其他方法
    高精度移相(MCP41xx)程序stm32F103,F407通用,更改引脚即可(SPI软件模拟通信)
    算法基础习题—内存分配(区间树实现)
    【大数据分析】graphscope开发环境搭建
    java计算机毕业设计springboot+vue基本微信小程序的汽车租赁租车小程序
    JavaEE:多线程(3):案例代码
    7.29模拟赛总结
    跟循泰国国内游宣传曲MV,像本地人一样游曼谷
    Revit MEP中连接件的巧妙定位?及管线快速连接?
  • 原文地址:https://www.cnblogs.com/binary1110011/p/16886299.html