• Codeforces Round #640(div.4) 题解


    A. Sum of Round Numbers

    ​ 将某个整数,分解为最少个数的形如x000的数之和(1 <= x <= 9,x右侧0的个数 >= 0).

    • 直接从个位开始拆,当某位上数字非0时记录。
    	cin >> t;
    	while(t--){
    		idx = 0,a = 1;
    		cin >> n;
    		while(n){
    			if(n % 10) book[idx++] = (n % 10) * a;
    			a *= 10;
    			n /= 10;
    		}
    		cout << idx << endl;
    		for(int i = 0; i < idx; i++){
    			cout << book[i] << ' ';
    		}
    		if(t) cout << endl;
    	}
    
    B. Same Parity Summands

    ​ 给你一个整数n,要求拆成k个奇数或者k个偶数的和

    • n为奇数,只有奇数才可以凑出来
      • 判断k的奇偶性,k 是否大于n,前k - 1个奇数使用1,计算最后一个奇数的值
    • n为偶数
      • 偶数个奇数 - k是否大于n,前k - 1个奇数使用1,计算最后一个奇数的值
      • 偶数 -- 判断2 * k是否大于n,前k - 1个偶数使用2,计算最后一个偶数
    	cin >> t;
    	while(t--){
    		cin >> n >> k;
    		if(n & 1){//奇数 奇数 
    			if(k & 1 && k <= n){
    				cout << "YES" << endl;
    				for(int i = 0; i < k - 1; i ++) cout << "1 ";
    				cout << n - k + 1 << endl;
    			}else cout << "NO" << endl;
    		}else{
    			if(2 * k <= n){//偶数 奇数个 只能用偶数 偶数个 均可 
    				cout << "YES" << endl;
    				for(int i = 0; i < k - 1; i++) cout << "2 ";
    				cout << n - (k - 1) * 2 << endl;				
    			}else if(!(k & 1) && k <= n){
    				cout << "YES" << endl;
    				for(int i = 0; i < k - 1; i++) cout << "1 ";
    				cout << n - k + 1 << endl;
    			}else cout << "NO" << endl;
    		}
    	}
    
    C.K-th Not Divisible by n

    ​ 输入n,寻找第k个不能被n整除的数

    • 从1开始,每n个数一组,每组中均有n - 1个数不可以被n整除
    • 当k可以整除n - 1,第k个为 n * k - 1
    • 第k个为k + i (i = k / (n - 1)): i * n + k - i * (n - 1) = k + i
    	cin >> t;
    	while(t--){
    		cin >> n >> k;
    		i = k / (n - 1);//每n个数you n-1个 
    		if(i * (n - 1) == k) cout << n * i - 1 << endl;
    		else cout << k + i << endl;
    	}
    
    D. Alice, Bob and Candies

    ​ 模拟,a and b每次吃的糖果总大小要最大且吃的糖果个数尽可能少。

    	cin >> t;
    	while(t--){
    		cin >> n;
    		vector<int> ar(n);
    		for(int i = 0;i < n; i++) cin >> ar[i];
    		i = st = 0;//st 吃糖果次数 i j :a b的索引
    		j = n - 1;
    		s_a = s_b = mx = 0;//s_a,s_b:a,b吃的所有糖果的总大小
    		while(i <= j){
    			a = 0;//a这一次吃的糖果总大小
    			++st;
    			for(; i <= j && a <= mx; i++) a += ar[i];
    			s_a += a;
    			if(a > mx) mx = a;
    			if(i > j) break;
    			b = 0;//b
    			++st;
    			for(; j >= i && b <= mx; j--) b += ar[j];	
    			s_b += b;
    			if(b > mx) mx = b;
    			if(i > j) break;
    		}
    		cout << st << ' ' << s_a << ' ' << s_b << endl;
    	}
    
    E.Special Elements

    ​ 一个数组中,存在一些特殊元素:数组中存在一些区间和 == a[i];求出数组中特殊元素个数。

    • 1 <= n <= 8000,1 <= a[i] <= n
    • n最大直到8000,所以O(n^2)以内的算法均可。
    • 使用前缀和,直接计算所有的区间和,同时判断是否 <= n,若是,则记录下来(记录数组范围 <= n)
    • 遍历数组,计算数组中有多少个元素被记录
    int ans,t,v,n,a[8010],s[8010],book[8010];//需要处理的最大范围:[1,8000] 
    //数据量很小,暴力+前缀和 记录所有的长度大于2的子序列和 找符合条件的 
    int main(void){
    	ios::sync_with_stdio(false);
    	cin.tie(0);cout.tie(0);
    	cin >> t;
    	while(t--){
    		ans = s[0] = 0;
    		memset(book,0,sizeof(book));
    		cin >> n;
    		for(int i = 1; i <= n; i++){//索引从1开始,避免处理边界问题
    			cin >> a[i];
    			if(i > 1){
    				s[i] = s[i - 1] + a[i];
    				for(int j = 0; j < i - 1; j++){//r - l >= 2
    					v = s[i] - s[j];
    					if(v <= n && !book[v]) book[v] = 1;
    				} 
    			}else s[i] = a[i];
    		}
    		for(int i = 1; i <= n; i++) if(book[a[i]]) ++ans;
    		cout << ans << endl;
    	}
    	return 0;
    } 
    
    F. Binary String Reconstruction

    ​ 输入n0,n1,n2分别代表"00","01","11"串的个数。构造含有这些子串的01串。

    • 首先,如果n1 == 0。结果只会是00.. or 11.. 串(n0 +1 or n2 + 1个)

    • n1不为0时,先生成00串(n0 + 1个 0),再加上01串(n0为0,先添加一个0;交替添加n1个 1 or 0)

    • 最后,添加11串。在之前生成的字符串中找到最后一个1所在位置,插入n2个1。(插入到其它1所在的位置也可以)

    string s;
    int main(void){
    	ios::sync_with_stdio(false);
    	cin.tie(0);cout.tie(0);
    	cin >> t;
    	while(t--){
    		cin >> n0 >> n1 >> n2;
    		if(!n1){//不存在01则n0 or n1有一个也为0 
    			if(!n0) cout << string(n2 + 1,'1');//n2 + 1
    			else cout << string(n0 + 1,'0');//n0 + 1
    			cout << endl;
    			continue;
    		}
    		s = "";
    		if(n0) s = string(n0 + 1,'0');
    		//01010...  n1奇偶性不同最终结尾数字不同 -- 把11串插到1相邻位置中间 
    		if(!n0) s += '0';//n0为0,补一个0 
    		for(int i = 0; i < n1; i++){
    			if(i & 1) s += '0';
    			else s += '1';
    		}
    		if(n2){
    			string a = string(n2,'1');
    			//11串有n2对 n2 + 1个 
    			//for(int i = 0; i < n2; i++) a += '1';
    			if(s[s.length() - 1] == '1') s += a;
    			else s.insert(s.length() - 2,a);
    		} 
    		cout << s << endl;	
    	}
    	return 0;
    } 
    
    G. Special Permutation

    ​ 长为n的数组中,1~n每个数字只出现一次,在这个数组中,相邻元素差的绝对值的范围[2,4]。

    • 贪心:
      • n < 4,无解
      • 从大到小输出小于等于n的所有奇数。
      • 输出“4 2”
      • 输出所有小于等于n的偶数
      • method2::先输出偶数,但是n == 4的时候需要特判,之后输出"5,1,3",其它奇数升序
    int main(void){
    	ios::sync_with_stdio(false);
    	cin.tie(0);cout.tie(0);
    	cin >> t;
    	while(t--){
    		cin >> n;
    		if(n < 4) cout << "-1";
    		else{
    			s = n;
    			if(!(s & 1)) --s;//先奇数
    			while(s > 0){
    				cout << s << ' ';
    				s -= 2;
    			} 
    			cout << "4 2";
    			s = 6;
    			while(s <= n){
    				cout << ' ' << s;
    				s += 2;
    			}
    		}
    		cout << endl;
    	}
    	return 0;
    } 
    
  • 相关阅读:
    Dubbo使用
    JVM内存分配及GC简述
    深入理解ThreadLocal
    Java的Timer定时器
    https与http的区别
    SpringBoot微服务
    Java的BIO,NIO,AIO
    Java常量池
    Java中的值传递与引用传递
    面向对象三大特征及代码优化七大原则
  • 原文地址:https://www.cnblogs.com/honey-cat/p/12872577.html
Copyright © 2020-2023  润新知