zoukankan      html  css  js  c++  java
  • K-th Beautiful String(规律)

    传送门

    思路

    • 观察发现左边的b的移动是呈等差数列的

    • 其位置为-2 -3 -3 -4 -4 -4 -5 -5 -5 -5 ... ,那么右边的b的最左位置是左边b的位置+1

    也就是说,给定K的值,只需要判断k是在哪一组就能确定左边的b的位置了,假设是第m组,那么左边b的位置就是n - m
    接着就是确定右边b的位置,而它的位置只需要判断它是在这一组的第几个数就够了,假设是第q个数,那么右边b的位置就是n - q + 1

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int N = 100010;
    char str[N];
    int main(){
    	int t;
    	cin >> t;
    	while(t --){
    		int n, k;
    		cin >> n >> k;
    		ll ans = 0;
    		for(ll i = 1; i <= n; i ++){
    			if((i * i + i) / 2 >= k && ((i - 1) * (i - 1) + (i - 1)) / 2 < k){
    				ans = i;
    				break;
    			}
    		} 
    		ll right = k - ((ans - 1) * (ans - 1) + (ans - 1)) / 2;
    		for(int i = 1; i <= n; i ++)
    			str[i] = 'a';
    		str[n - ans] = 'b';
    		str[n - right + 1] = 'b';
    		for(int i = 1; i <= n; i ++)
    			cout << str[i];
    		cout << endl;
    		
    	}
    	
    	return 0;
    }
    /*   //本来还想用二分做,但写起来太麻烦,出错了,就直接O(N)了
    int l = 1, r = 100010;
    		int mid = 0;
    		while(l < r){
    			mid = l + r + 1 >> 1;
    			if((mid * mid + mid) / 2 >= k && (((mid - 1) * (mid - 1) + (mid - 1))) / 2 < k)
    				break;
    			else if((mid * mid + mid) / 2 < k)
    				l = mid;
    			else if((mid * mid + mid) / 2 >= k && (((mid - 1) * (mid - 1) + (mid - 1))) / 2 >= k)
    				r = mid - 1;
    		}
    		for(int i = 1; i <= n; i ++)
    			str[i] = 'a';
    		str[n - mid + 1] = 'b';
    		int t = k - ((mid - 1) * (mid - 1) + (mid - 1)) / 2;
    		str[n - t + 1] = 'b';
    		for(int i = 1; i <= n; i ++)
    			cout << str[i];
    		cout << endl;
    	*/
    
  • 相关阅读:
    C#中调用DTS
    经典问题:向setTimeout传递函数参数
    C#.NET 中的类型转换
    SQL语句导入导出大全 (转载)
    js脚本defer的作用
    [转]使用 Java API 处理 WebSphere MQ 大消息
    WideCharToMultiByte 宽字节转换为多字节
    [原].NET数据库开发中请注意区域时间格式
    输出页眉和页脚的简单HTTP模块实践
    浅析ASP.NET HTTP Module
  • 原文地址:https://www.cnblogs.com/pureayu/p/14418168.html
Copyright © 2011-2022 走看看