zoukankan      html  css  js  c++  java
  • 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<<'
    ';
    		}else if(id==2){
    			cout << 6<<'
    ';
    		}else if(id==1){
    			int cnt = -1,cnt2 = 0;
    			forn(i,n){
    				if(a[i]) cnt++;
    				else cnt2++;
    			}
    			cout<<2*cnt+2*cnt2<<'
    ';
    		}else cout<<1ll*n*(1+n)/2<<'
    ';	
    	}	
    	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 << '
    ';
        }
        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]<<'
    ';
            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<<'
    ';
            }else cout<<"Impossible"<<'
    ';     
        }
        return 0;
    }
    
    人一我百,人十我万。
  • 相关阅读:
    BZOJ 3744 Gty的妹子序列
    BZOJ 3872 Ant colony
    BZOJ 1087 互不侵犯
    BZOJ 1070 修车
    BZOJ 2654 tree
    BZOJ 3243 向量内积
    1003 NOIP 模拟赛Day2 城市建设
    CF865D Buy Low Sell High
    CF444A DZY Loves Physics
    Luogu 4310 绝世好题
  • 原文地址:https://www.cnblogs.com/AlexPanda/p/12520313.html
Copyright © 2011-2022 走看看