Codeforces Round #668 (Div. 2)A-C

Codeforces Round #668 (Div. 2)

A. Permutation Forgery

问题分析:

就是要求找一个 新的序列 只需要吧 整个序列倒着输出 就符合 要求

AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define mem(a,b) memset((a),(b),sizeof(a));
const ll inf=0x3f3f3f3f;//1061109567,2*未超int,allinf=mem(a,0x3f,sizeof(a));
const int N=2e5+10;
int main(){
     
       // #define io
#ifdef io
        freopen("in.txt","r",stdin);
#endif
    cin.tie(0);
    int t,n;
    int a[1003];
    cin>>t;
    while(t--){
     
        cin>>n;
        for(int i=0;i<n;i++){
     
            cin>>a[i];
        }
        for(int i=n-1;i>=0;i--){
     
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

B. Array Cancellation

问题分析:

。。。。自己是用双指针 跑的两种情况 感觉很麻烦,,,
看了下CF大佬的代码 ,。,,,
其时很简单,,就是从头扫到尾部
前缀和 当前缀和小于0 就是需要花的金币
为啥哈,,,,因为当前缀和小于0的时候 也就是说当 i 完全不够去 使者一项 归零 只有 通过加上后面的项才行。。
也就是 i>j 情况

大佬AC代码:

/* 	* In the name of GOD 
	* Thanks God */
#include 
 
using namespace std;
 
typedef long long ll;
typedef long double ld;
#define F first
#define S second
#define int long long
const int N = 101234;
int a[N];
 
void solve() {
     
	int n;
	cin >> n;
	int x = 0, ans = 0;
	for (int i = 0; i < n; i++) {
     
		cin >> a[i];
		x += a[i];
		if (x < 0) {
     
			ans += -x;
			x = 0;
		}
	}
	cout << ans << ' ';
}
 
int32_t main() {
     
	int t = 1;
	cin >> t;
	while (t--) {
     
		solve();
	}
}

在下的代码,,,,

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define mem(a,b) memset((a),(b),sizeof(a));
const ll inf=0x3f3f3f3f;//1061109567,2*未超int,allinf=mem(a,0x3f,sizeof(a));
const int N=1e5+10;
int a[N];
int main(){
     
       // #define io
#ifdef io
        freopen("in.txt","r",stdin);
#endif
    cin.tie(0);
    int t,n;
    cin>>t;
    while(t--){
     
        cin>>n;
        for(int i=0;i<n;i++){
     
            cin>>a[i];
        }
        ll  ans=0;
        for(int i=0,j=0;i!=n&&j!=n;){
     
            while(a[i]<=0){
     
                if(i>=n)break;
                i++;
            }
            while(a[j]>=0||j<=i){
     
                if(j>=n) break;
                j++;
            }
            if(a[j]<0&&a[i]>0&&i<j){
     
                int x=min(a[i],abs(a[j]));
                a[i]-=x;
                a[j]+=x;
            }
        }
        for(int i=0,j=0;i!=n&&j!=n;){
     
            while(a[i]<=0){
     
                if(i>=n)break;
                i++;
            }
            while(a[j]>=0){
     
                if(j>=n) break;
                j++;
            }
            if(a[j]<0&&a[i]>0){
     
                int x=min(a[i],abs(a[j]));
                a[i]-=x;
                a[j]+=x;
                ans+=x;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

C. Balanced Bitstring

问题分析:

要求妹k个字符内 0/1的数量相等
在第一组k 个字符 满足的条件下
每往后移动一位就相当于 吧 第一位 移动到 第二组k 的最后一位
只有这样才能满足

并且有与 已知序列 我们可以推断出第一组应该是什么
也就是说 1 k+1 1+2*k …这些项必须相等

然后我们来看一下不满足条件的几种情况:

  1. 1、 k+1 、 1+2*k …这些项中有冲突 也就是 有不相等的
  2. 每一组中k个字符 中0/1的数量不相等(可能存在 从头到尾 都是 ?)
    也就是说这种情况可以转换成 0/1的数量超过k/2
    /* 6 2 1?1?1? 这种情况就是0/1不相等 但是。。。*/

AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define mem(a,b) memset((a),(b),sizeof(a));
#define lowbit(a) ((a)&-(a))
const ll inf=0x3f3f3f3f;//1061109567,2*未超int,allinf=mem(a,0x3f,sizeof(a));
const int N=3e5+10;
int main(){
     
       // #define io
#ifdef io
        freopen("in.txt","r",stdin);
#endif
        cin.tie(0);
        int t;
        cin>>t;
        while(t--){
     
                int n,k;
                string s;
                cin>>n>>k>>s;
                int x,o,f;
                x=o=f=0;
                for(int i=0;i<n-k;i++){
     //通过前后两组推断/映射其他的
                        if(s[i]=='?') s[i]=s[i+k];
                        if(s[i+k]=='?') s[i+k]=s[i];
                        if(s[i]=='1'&&s[i+k]=='0') f=1;//冲突
                        if(s[i]=='0'&&s[i+k]=='1') f=1;
                }
                if(f){
     
                        cout<<"NO"<<endl;
                        continue;
                }
                for(int i=0;i<k;i++){
     x+=s[i]=='0',o+=s[i]=='1';}//统计第一项数量
                for(int i=k;i<=n;i++){
     
                        if(x>k/2||o>k/2) {
     //某一组 0/1数量超过k一半也就是0/1不等
                                f=1;
                                break;}
                        if(i==n) break;
                        x+=s[i]=='0',o+=s[i]=='1';//问题分析第三行
                        x-=s[i-k]=='0',o-=s[i-k]=='1';
                }
                cout<<(f?"NO":"YES")<<endl;
        }
        return 0;
}

你可能感兴趣的:(CodeForces)