2018青岛区域赛训练总结及cde题解

这场一开始st卡在了IO的上面T了两发,我wa了两发c,有一些情况没有考虑到。50mins的时候我看st代码,发现没问题大胆换了IO,AC,跟st讲了2minsC的时候发现了wa点,改了AC。随后cxy也AC了J题。大概过了快1小时,我们做不下去了,退场补题,发现DE还是可以做的,对标区域赛铜尾,如果DE开出来可能能进到银尾。
总结:

  1. IO必须开。
  2. 现场赛签到还是和队友讨论后交。
  3. E题没有耐心想下去。
    M J是队友写的,貌似也是签到不写了。
    题解:
    C
    题意:给你2个01串,你可以选择两个区间将区间内的所有数0变1,1变0。问有几种方法把他变为一样。卡O1
    思路:
    如果有两个联通块区间不一样那么方案数为6。
    如果都一样那么方案数为(n+1)*n/2
    如果只有1个,那么方案数为不一样的个数(cnt-1)2+一样的个数cnt22
    此外0
    代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define forn(i,n) for(int i=0;i<n;i++)
#define for1(i,n) for(int i=1;i<=n;i++)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
const int inf = 0x3f3f3f3f;
const ll INF =0x3f3f3f3f3f3f3f3f;

int main(){
	IO;
	int t;cin>>t;
	while(t--){
		int n;cin>>n;
		string s,t;cin>>s>>t;
		vector<int>a;
		forn(i,n){
			if(s[i]==t[i]) a.push_back(0);
			else a.push_back(1);
		}
		int id = 0;
		forn(i,n)if(a[i]){
			if(i&&a[i-1]);
			else id++;
		}
		if(id>2){
			cout<<0<<'\n';
		}else if(id==2){
			cout << 6<<'\n';
		}else if(id==1){
			int cnt = -1,cnt2 = 0;
			forn(i,n){
				if(a[i]) cnt++;
				else cnt2++;
			}
			cout<<2*cnt+2*cnt2<<'\n';
		}else cout<<1ll*n*(1+n)/2<<'\n';	
	}	
	return 0;	
}

E
题意:从1点出发每到一个点这个点的权值增长ai,问走了m次后,让所有点权值最小值最大。
思路:典型的二分题,只是被题意蒙蔽了双眼,想了个其他的二分,不想写了。
二分ans,主要judge比较坑难写。
我们先算出每个点到达lim需要访问至少几次,然后那么ai走了5次,ai+1要至少走5次。
所以每个点走的次数就是x(当前点至少访问次数)+x-1(需要消耗来回拐弯)。加一些特判和修改就写成了代码的样子。
代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define forn(i, n) for (int i = 0; i < n; i++)
#define for1(i, n) for (int i = 1; i <= n; i++)
#define IO                       \
    ios::sync_with_stdio(false); \
    cin.tie(0);                  \
    cout.tie(0)
const int maxn = 1e5 + 5;

ll a[maxn], n, m;

bool check(ll lim) {
    ll sum = 0, x = 0, y = 0;
    forn(i, n) {
        x = (lim - 1) / a[i] + 1;
        x -= y;
        if (x <= 0) {
            if (i != n - 1)
                x = 1;
            else
                x = 0;
            y = 0;
        } else
            y = x - 1;
        sum += x + y;
        if (sum > m) return 0;
    }
    return 1;
}

int main() {
    IO;
    int t;
    cin >> t;
    while (t--) {
        cin >> n >> m;
        forn(i, n) cin >> a[i];
        ll l = 1, r = 1e17 + 1;
        while (l <= r) {
            ll mid = l + r >> 1;
            if (check(mid))
                l = mid + 1;
            else
                r = mid - 1;
        }
        cout << l - 1 << '\n';
    }
    return 0;
}

D.
题意:给一串数字,他由下图构成。这里的+号代表放在后面。问构成这串数字最小字典序的AB是多少。在这里插入图片描述
思路:
想明白一点,如果x = ai*bi,那么x肯定>ai||>bi。所以我们枚举a0的9种可能来爆搜判断。
代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define forn(i,n) for(int i=0;i<n;i++)
#define for1(i,n) for(int i=1;i<=n;i++)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
const int maxn = 2e5+5;
int n,m,pos,a[maxn],b[maxn],len;char s[maxn];

bool getb(){
    forn(i,m){
        int x = s[pos++] - '0';
        if(a[0]>x&&x) x = x*10+s[pos++]-'0';//cerr<<x<<' '<<a[0]<<'\n';
        if(x%a[0]==0&&x/a[0]<10) b[i] = x/a[0];
        
        else return 0;
    }
    return 1;
}

bool geta(){
    for1(i,n-1) {
        int x = s[pos++] - '0';
        if(b[0]>x&&x) x = x*10+s[pos++]-'0';
        if(x%b[0]==0&&x/b[0]<10) a[i] = x/b[0];
        else return 0;
        for1(j,m-1) {
            int x = s[pos++] - '0';
            if(a[i]>x&&x) x = x*10+s[pos++]-'0';
            if(a[i]*b[j]!=x) return 0;
        }
    }
    return 1;
}

bool solve(){
    int one = s[0]-'0';
    len = strlen(s);
    for1(i,9)if(one%i==0){
        pos = 0;
        a[0] = i;
        if(getb()&&geta()&&pos==len)return 1;
    }
    int two = one*10+s[1]-'0';
    for1(i,9)if(two%i==0&&two/i<10){
        pos = 0;
        a[0] = i;
        if(getb()&&geta()&&pos==len)return 1;
    }
    return 0;
}

int main(){
    IO;
    int t;cin>>t;
    while(t--){
        cin>>n>>m;
        cin>>s;
        if(solve()){
            forn(i,n) cout<<a[i];
            cout<<' ';
            forn(i,m)cout<<b[i];
            cout<<'\n';
        }else cout<<"Impossible"<<'\n';     
    }
    return 0;
}
posted @ 2019-08-13 14:08  AlexPanda  阅读(149)  评论(0编辑  收藏  举报