Codeforces Round #710 (Div. 3)

Codeforces Round #710 (Div. 3)

A. Strange Table

题意:给定一个n*m的矩阵,其为列递增现在变为行递增

现在给定一个数x问图一中的x在图2中是什么数字

解题思路:数学计算新生成的坐标,然后输出即可

解题代码:

#include <iostream>
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int max = 2e5+10;
signed main(){
	int t,n,m,x;
	cin >> t; 
	while(t--){
		cin >> n >> m >> x;
		int ta,tb;
		ta = x % n;
		if(ta==0) ta =n ;
		tb = (x-ta)/n+1;
		cout << (ta-1)*m + tb <<endl;
	}
	return 0;
} 

B. Partial Replacement

题意:

给定一个由‘x’和’*‘组成的长度为n字符串,将其中的某些’*‘用’x’替代,且要求头尾的’*‘必须被替代为’x’,且两个’x’之间的距离(下标之差)不得超过给定的k

题解:电线杆问题,贪心经典,从第一个变化的符号开始取,差不超过k的都可以拿走

解题代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
	int t,n,k,ans,npos,fi,la;
	string s;
	cin>>t;
	while(t--){
		cin >> n >> k;
		cin >> s;
		vector<int>vc;
		for(int i=0;i<s.length();i++){
			if(s[i]=='*'){
				vc.push_back(i);
			}
		}
		fi = vc[0];
		la = vc.back();
		if(fi==la || la-fi<=k){
			if(fi==la) cout<<"1\n";
			else cout<<"2\n";
			continue;
		}
		ans = 2;
		npos = fi;
		while(npos+k < la){
			if(s[npos+k]=='*')npos += k; 
			else{
				npos += k;
				while(s[npos]!='*') npos--;
			}
			ans++;
		}
		cout<<ans<<endl;
	} 
	return 0;
}

C. Double-ended Strings

题意:给定两个字符串,可以删除头尾元素,问最少要惊醒多少次操作才能使的两个串相等

解题思路:最长公共子串问题,最终数出的答案为两个串的长度和减去两倍的子串长度

解题代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
const int maxn = 120;
int dp[maxn][maxn];
signed main(){
	int t;
	cin>>t;
	int len1,len2,n,ans=0,tres;
	while(t--){
		ans = tres = 0;
	    string s1,s2;
	    cin>>s1>>s2;
	    len1 = s1.length();
	    len2 = s2.length();
	    memset(dp,0,sizeof dp);
	    for(int i=0;i<len1;i++){
	    	for(int j=0;j<len2;j++){
	    		if(s1[i]==s2[j]) dp[i][j]=1;
			}
		}
	        
	    for(int i=0;i<len1;i++){
	        tres=0;
	        for(int j=0;j<len2;j++){
	            if(dp[i+j][j]==1){
	            	tres++;
				}else{
	            	 tres = 0;
				}
				ans = max(ans,tres);
	        }
	    }
	    
	    for(int i=0;i<len2;i++){
	        tres = 0;
	        for(int j=0;j<len1;j++){
	            if(dp[j][i+j]==1){
	            	tres++;
				}else{
	            	tres = 0;
				}
	            ans = max(ans,tres);
	        }
	    }
	    printf("%d\n",s1.length()+s2.length()-2*ans);
	} 
	return 0;
}

D. Epic Transformation

题意:给定长度为n的数组,可以选择里面不同的两个元素删除,问最后剩下的元素最小个数是多少

题解思路:简单贪心,删除数字只与出现最多的数字的出现次数有关,如果其超过一半,那么最后他会有剩余,如果他不足,那么如果他是偶数,那么最后不会有数字剩下,如果为奇数,那么会剩下的数字为1

解题代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
const int maxn = 120;
int dp[maxn][maxn];
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t,n;
	cin>>t;
	while(t--){
		cin >> n;
		int tnum = -1;
		int tleft = 0;
		int tmp;
		vector<int>vc;
		map<int,int>mp;
		for(int i = 0;i<n;i++){
			cin >> tmp;
			if(mp[tmp] == 0){
				mp[tmp] =1;
				vc.push_back(tmp);
			}else{
				mp[tmp]+=1;
			}
		}
		int mx = -1;
		for(int i = 0;i<vc.size();i++){
			mx = max(mx,mp[vc[i]]);
		}
		if(mx > n-mx){
			cout << mx - n + mx << endl;
		}else{
			if(n%2)cout << 1 << endl;
			else cout << 0 << endl;
		}
	} 
	return 0;
}

E. Restoring the Permutation

题意:给出一个数列pi表示排列a的前i项(1<=i<=n)的最大值,要求分别求出字典序最大与最小的原排列。

解题思路:

对于字典序最小,其余位置按照剩余数字从小到大填充即可,对于字典序最大,在每一个ai未确定的位置,找出比pi小的数字中没有被使用过且最大的数字填充进去即可。

解题代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main() { 
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--){
	    int n;
	    cin >> n;
	    vector<int> q(n);
	    for (auto &x : q) cin >> x;
	    set<int> nums;
	    for (int i = 1; i <= n; i++) nums.insert(i);
	    vector<int> per(n);
	    per[0] = q[0];
	    nums.erase(q[0]);
	    for (int i = 1; i < n; i++)
	        if (q[i] != q[i - 1]) {
	            per[i] = q[i];
	            nums.erase(q[i]);
	        }
	    } 
	    set<int> numssave = nums;
	    cout << q[0] << ' ';
	    for (int i = 1; i < n; i++) {
	        if (per[i] == 0) {
	            cout << *nums.begin() << ' ';
	            nums.erase(nums.begin());
	        } else {
	            cout << per[i] << ' ';
	        }
	    }
	    cout << '\n';
	    nums = numssave;
	    cout << q[0] << ' ';
	    for (int i = 1; i < n; i++) {
	        if (per[i] == 0) {
	            auto it = --nums.lower_bound(q[i]);
	            cout << *it << ' ';
	            nums.erase(it);
	        } else {
	            cout << per[i] << ' ';
	        }
	    }
	    cout << '\n';
        
    }
    return 0;
}  
上一篇:710


下一篇:树链剖分——线段树区间合并bzoj染色