zoukankan      html  css  js  c++  java
  • HDU 5431

    由于最长不超过30个字符(由K的范围确定),于是,枚举所有的字符串,二分中使用二分就可以确定第K小了。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    char str[20010];
    int bits[32];
    int save[32][20010];
    int tmp[32];
    
    int findindex(int i,int key){
    	int l=1,r=save[i][0];
    	int m,ans=0;
    	while(l<=r){
    		int m=(l+r)/2;
    		if(save[i][m]<=key){
    			ans=m;
    			l=m+1;
    		}		
    		else r=m-1;
    	}
    	return ans;
    }
    
    int main(){
    	int kase,now,T,K;
    	scanf("%d",&kase);
    	for(int i=1;i<32;i++) bits[i]=(1<<i);
    	while(kase--){
    		scanf("%s",str);
    		int len=strlen(str);
    		for(int i=0;i<31;i++) save[i][0]=0;
    		for(int i=0;i<len;i++){
    			now=0;
    			for(int j=i;j<=min(i+29,len-1);j++){
    				now=(now<<1)+(str[j]-'A');
    				save[j-i+1][++save[j-i+1][0]]=now;
    			}
    		}
    		for(int i=1;i<=30;i++) sort(save[i]+1,save[i]+save[i][0]+1);
    		for(int i=1;i<=30;i++) {
    			save[i][0]=unique(save[i]+1,save[i]+save[i][0]+1)-(save[i]+1);
    		//	cout<<save[i][0]<<endl;
    		}
    	//	cout<<(char)(save[1][1]+'A')<<endl;
    		scanf("%d",&T); int ans,ansbit;
    		while(T--){
    			scanf("%d",&K);
    			ans=-1;
    			for(int i=1;i<=30;i++){
    		//		cout<<K<<endl;
    				if(K>bits[i]-save[i][0]){
    					K-=(bits[i]-save[i][0]);
    					continue;
    				}
    				int l=0,r=bits[i]-1;
    				while(l<=r){
    					int m=(l+r)>>1;
    					int pos=findindex(i,m);
    			//		cout<<m<<" "<<pos<<endl;
    					if(K>m+1-pos) l=m+1;
    					else if(K<m+1-pos) r=m-1;
    					else{
    						ans=m;
    						while(ans==save[i][pos]&&pos!=0){
    							ans--; pos--;
    						}
    						break;
    					}
    				}
    		//		system("pause");
    				if(ans!=-1){
    					ansbit=i;
    					break;
    				}
    		//		else K-=(bits[i]-save[i][0]);
    			}
    			int cnt=0;
    		//	cout<<ans<<endl;
    			while(ansbit--){
    				tmp[cnt++]=ans%2;
    				ans/=2;
    			}
    			while(cnt--)
    				printf("%c",tmp[cnt]+'A');
    			puts("");
    			
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    如何将一棵树转化成二叉树
    雪碧图的使用
    CSS简介,引入方式,文字和文本样式设置
    表格Table和表单元素
    html 中< col>标签和< colgroup>标签的区别
    Emmet的HTML语法(敲代码的快捷方式)
    抖音风格字体效果
    几种有效减小电脑系统盘使用量的方法
    ubuntu 机器名称修改方法
    Ubuntu 为基于X应用程序增加启动项的正确做法
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4790931.html
Copyright © 2011-2022 走看看