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;
    }
    
    人一我百,人十我万。
  • 相关阅读:
    JTable使用
    VirtualBox 虚拟机安装
    ICONIX简介
    反射在Java Swing编程中的应用之java 模仿.net事件处理
    【Ubuntu】UBUNTU中如何获得root权限
    html头部代码【转载】
    eclipse code templates 设置
    include与jsp:include区别【转载】
    银行卡
    【AJAX】DWR入门教程
  • 原文地址:https://www.cnblogs.com/AlexPanda/p/12520313.html
Copyright © 2011-2022 走看看