B~F Java题解,代码已去除冗余
按规则模拟即可,时间复杂度O(Tklogn)
import java.util.*;
public class Main{
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
for(int t=sc.nextInt();t!=0;t--){
long n=sc.nextInt(),k=sc.nextInt(),ans=0;
while(n!=findInv(n)&&ans<k){
ans++;
n+=findInv(n);
}
System.out.println(n+" "+(n==findInv(n)?ans:-1));
}
}
static long findInv(long a){
long ans=0;
for(;a!=0;ans=ans*10+a%10,a/=10){}
return ans;
}
}
其实不管区间有多长,呢每个区间最多尝试10个数字,时间复杂度O(T(n+100))
import java.util.*;
public class Main{
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
int a[]=new int[500005];
for(int t=sc.nextInt();t!=0;t--){
int n=sc.nextInt(),l1=sc.nextInt(),r1=sc.nextInt(),l2=sc.nextInt(),r2=sc.nextInt();
for(int i=3;i<=n;i++){
a[i]=sc.nextInt();
}
boolean found=false;
for(int i=l1;i<=r1&&i<l1+10&&!found;i++){
a[1]=i%10;
for(int j=l2;j<=r2&&j<l2+10;j++){
a[2]=j%10;
found=true;
for(int k=3;k<=4&&k<=n;k++){
if(a[k-1]*a[k-2]%10!=a[k]){
found=false;
}
}
if(found){
System.out.println(i+" "+j);
break;
}
}
}
if(!found){
System.out.println("-1 -1");
}
}
}
}
两个数字可以变得相等,当且仅当它们都在同一个循环中,而又可以证明循环节长度为数字的二进制位数,时间复杂度O(32Tn)
import java.util.*;
public class Main{
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
for(int t=sc.nextInt();t!=0;t--){
int n=sc.nextInt(),a[]=new int[n],ans=0;
for(int i=0;i<n;i++){
a[i]=sc.nextInt();
}
for(int i=0,j=n-1;i<j&&ans>=0;i++,j--){
Map<Integer,Integer> map=new HashMap<>();
for(int k=0;!map.containsKey(a[i]);k++,a[i]^=a[i]>>1){
map.put(a[i],k);
}
ans=map.containsKey(a[j])?ans+Math.min(map.get(a[j]),map.size()-map.get(a[j])):-1;
}
System.out.println(ans);
}
}
}
每种洞数都有最小的数字可以达到,要么全用8,要么首位是4,当洞数是0则需要是1,因此贪心天池即可,时间复杂度O(T(n+10))
import java.util.*;
public class Main{
static long candidate[]={1,4,8,48,88,488,888,4888,8888,48888,88888,488888,888888,4888888,8888888,48888888,88888888,488888888,888888888,4888888888L,8888888888L};
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
for(int t=sc.nextInt();t!=0;t--){
int n=sc.nextInt();
long sum=Math.min(sc.nextLong(),n*candidate[20]);
if(sum<n){
System.out.println(-1);
}
else{
for(int i=20;i>=0;i--){
if(n*candidate[i]<=sum){
for(int j=0;j<n;j++){
System.out.print((j<(sum-candidate[i]*n)/(candidate[i+1]-candidate[i])?candidate[i+1]:candidate[i])+" ");
}
System.out.println();
break;
}
}
}
}
}
}
对于每个左边界,假设右边界比它大,那么若存在,这样的右边界有且仅有一个,就是最近的大约它的数,反向同理,但是需要去除最近的同值在区间内的情况,时间复杂度O(Tn)
import java.util.*;
public class Main{
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
for(int t=sc.nextInt();t!=0;t--){
int n=sc.nextInt(),a[]=new int[n],ans=0,next[]=new int[n];
Stack<Integer> stack=new Stack<>();
Map<Integer,Integer> map=new HashMap<>();
Arrays.fill(next,n);
for(int i=0;i<n;i++){
a[i]=sc.nextInt();
while(!stack.isEmpty()&&a[i]>a[stack.peek()]){
next[stack.pop()]=i;
}
stack.push(i);
}
for(int i=n-1;i>=0;i--){
if(next[i]<n&&next[i]-i>1&&next[i]<map.getOrDefault(a[i],n)){
ans++;
}
map.put(a[i],i);
}
stack.clear();
map.clear();
Arrays.fill(next,-1);
for(int i=n-1;i>=0;i--){
while(!stack.isEmpty()&&a[i]>a[stack.peek()]){
next[stack.pop()]=i;
}
stack.push(i);
}
for(int i=0;i<n;i++){
if(next[i]>=0&&i-next[i]>1&&next[i]>map.getOrDefault(a[i],-1)){
ans++;
}
map.put(a[i],i);
}
System.out.println(ans);
}
}
}