A题
看有几个1和3,统计输出即可
B题
给出a/b/c,找到x,y使得x的位数是a,y的位数是b,gcd(x,y)的位数是c
解:刚开始没想出太好的解,就暴力打表然后存进去的,太麻烦啦
假设x,y初始都为任意一个位数为c的值z,然后x不断3直到位数符合要求,y不断5直到符合要求,这样可以保证gcd的值一定是z,并且因为每次乘3/5,每次乘位数最多增加1
import java.util.Scanner; public class Main { public static long ksm(long a,long c) { // TODO Auto-generated method stub long s = 1; while(c != 0) { if((c & 1) != 0) s *= a; a *= a; c >>= 1; } return s; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); while(n-- != 0) { long a = sc.nextLong(); long b = sc.nextLong(); long c = sc.nextLong(); long cc = ksm(10,c - 1); //System.out.println("cc = " + cc); long aa = cc; long bb = cc; while(true) { if((long)(Math.log10(aa)) + 1 == a) break; aa *= 3; } while(true) { if((long)(Math.log10(bb))+ 1 == b) break; bb *= 2; } System.out.println(aa + " " + bb); } } }
C题
题意:n张卡片从上到下放置,每张卡片都有一个颜色,q个询问,每次给出颜色t,找到最上面的颜色为t的卡片的位置,并把它放在最上面。
解:可以发现,我们用到的信息只有每种颜色最上面的那张卡片位置,其他的都不需要
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(),q = sc.nextInt(); int[] pos = new int[100]; for(int i = 1;i <= 50; ++i) pos[i] = n; for(int i = 1;i <= n; ++i) { int x = sc.nextInt(); pos[x] = Math.min(i,pos[x]); } for(int i = 1;i <= q; ++i) { int x = sc.nextInt(); System.out.print(pos[x] + ((i == q)?"\n":" ")); for(int j = 1;j <= 50; ++j) if(pos[x] > pos[j]) pos[j]++; pos[x] = 1; } } }
D题
题意:每个串的代价是i和j的对数,满足s[i] = s[j]且s[i + 1] = s[j + 1],构造一个只由前k种小写字母组成的长度为n的字符串,使其代价最小。
解:构造方法a ab ac ad .....b bc bd ..... c ...这样构造不会产生代价,如果n大于这个长度,那么多次重复这个串即可
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(),k = sc.nextInt(); String s = ""; for(char i = 'a';i < 'a' + k; ++i) for(char j = i;j < 'a' + k; ++j) if(i == j) s = s + i; else s = s + i + j; while(n > s.length()) { System.out.print(s); n -= s.length(); } if(n <= s.length()) System.out.println(s.substring(0, n)); } }