hist icpc集训队选拔第一天训练
1A - Almost Rectangle CodeForces - 1512B
https://codeforces.com/problemset/problem/1512/B
题解:就是给出一个nn的矩阵,然后给出的矩阵中有两个坐标点为,然后组成一个矩形,
先找出来两个*的坐标,然后分为三种情况,同行,同列,不同行且不同列。
1:同行的时候,列变化,分两种情况是不是边缘,
同行,不同行且不同列和上面一样
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while(t-->0) {
int n = sc.nextInt();
char[][] c = new char[n][n];
for (int j = 0; j < n; j++) {
String string = sc.next();
c[j] = string.toCharArray();
}
int[][] arr = new int[2][2];
int index = 0;
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
if (c[j][k] == '*') {
arr[index][0] = j;
arr[index][1] = k;
index++;
}
}
}
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
int x1 = arr[0][0];
int y1 = arr[0][1];
int x2 = arr[1][0];
int y2 = arr[1][1];
if (arr[0][0] != arr[1][0] && arr[0][1] != arr[1][1]) {
int dy = y2 - y1;
c[x1][y1 + dy] = '*';
c[x2][y2 - dy] = '*';
} else if (arr[0][0] == arr[1][0]) {
if (x1 + 1 == n) {
c[x1-1][y1] = '*';
c[x2-1][y2] = '*';
}else {
c[x1+1][y1] = '*';
c[x2+1][y2] = '*';
}
} else if (arr[0][1] == arr[1][1]) {
if (y1 + 1 == n) {
c[x1][y1-1] = '*';
c[x2][y2-1] = '*';
}else {
c[x1][y1+1] = '*';
c[x2][y2+1] = '*';
}
}
System.out.print(c[j][k]);
}
System.out.println();
}
}
}
}
B - A-B Palindrome CodeForces - 1512C
题目链接
题解:给出两个数a,b以及一个字符串,字符串有0,1,?组成,且长度为a+b,然后?可以变化为0和1,最后字符串中有a个0,b个1还是回文串.
首先遍历一下字符串,算出有多少0,1。
然后开始遍历字符串,
若是c[i]!=c[n-i+1]还都等于?,这样直接跳出循环,这样就不是回文串。
若是c[i]==c[n-i+1]就可以跳过,若是等于?了那就到后面凑0,1
多是c[i]!=c[n-i+1],是0吧?变成0,是1把?变成1,
这时候的同时为?情况还没有解决,那就要在遍历一次,
然后再考虑长度是否为奇偶数,
若是0少一且1够,或者1少一且0够。若不是不符合。
这次遍历3次字符串,虽然复杂,但是一步步来得,会很清楚
import java.util.Scanner;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while(t-->0) {
int a = sc.nextInt();
int b = sc.nextInt();
String str = sc.next();
int n = str.length();
str="0"+str;
char c [] = str.toCharArray();
int suma=0;
int sumb=0;
for(int i=1;i<=n;i++) {
if(c[i]=='0') {
suma++;
}
if(c[i]=='1') {
sumb++;
}
}
boolean bool = true;
for(int i=1;i<=n/2;i++) {
if(c[i]!=c[n-i+1]&&c[i]!='?'&&c[n-i+1]!='?') {
bool = false;
}else if(c[i]=='?'&&c[n-i+1]!='?'){
if(c[n-i+1]=='0') {
c[i]='0';
suma++;
}
else {
c[i]='1';
sumb++;
}
}else if(c[i]!='?'&&c[n-i+1]=='?'){
if(c[i]=='0') {
c[n-i+1]='0';
suma++;
}
else {
c[n-i+1]='1';
sumb++;
}
}
}
for(int i=1;i<=n/2;i++) {
if(c[i]=='?'&&c[n-i+1]=='?'){
if(suma<=a-2) {
c[i]='0';
c[n-i+1]='0';
suma+=2;
}
else if(sumb<=b-2) {
c[i]='1';
c[n-i+1]='1';
sumb+=2;
}
}
}
if((n)%2==1) {
if(c[n/2+1]=='?') {
if(suma==(a-1)&&b==sumb){
c[n/2+1]='0';
suma++;
}else if(sumb==(b-1)&&a==suma) {
c[n/2+1]='1';
sumb++;
}else {
bool = false;
}
}
}
if(suma==a&&sumb==b&&bool) {
for(int i=1;i<=n;i++) {
System.out.print(c[i]);
}
System.out.println();
}else {
System.out.println(-1);
}
}
}
}
C - Corrupted Array CodeForces - 1512D
题目链接
题解:题给出两个数组a,b,一个数组长度为n,一个为n+2.
再b数组中有n个数是A数组,然后BN+1等于A数组的N项合。或者bn+2=x。x属于A数组。
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t=sc.nextInt();
while(t-->0) {
int n=sc.nextInt();
Long b[]=new Long[n+2];
for(int i=0;i<n+2;i++) {
b[i]=sc.nextLong();
}
Arrays.sort(b);
long sum=0;
for(int i=0;i<n+1;i++) {
sum+=b[i];
}
int id=-1;
for(int i=0;i<n;i++) {
if((sum-b[i])==b[n+1]) {
id=i;
break;
}
}
if(id==-1) {
sum-=b[n];
if(sum==b[n+1]) id=n;
else if(sum==b[n]) id=n;
}
if(id==-1) {
System.out.println(-1);
}
else {
for(int i = 0;i < n + 1;i ++)
{
if(i != id) {
System.out.print(b[i] + " ");
}
}
}
}
}
}
D - Double-ended Strings CodeForces - 1506C 题目链接
题解:题给出两个字符串然后算两个字符串的最大公共子串,且去掉元素最少
首先判断两个字符串是否一样,一样输出0
然后遍历两个字符串
import java.util.HashSet;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t=sc.nextInt();
while(t-->0) {
String str1=sc.next();
String str2=sc.next();
if(str1.equals(str2)) {
System.out.println(0);
}else {
int ans=0;
for(int i=0;i<str1.length();i++) {
int l=0;
for(int j=0;j<str2.length();j++) {
if(str1.charAt(i)==str2.charAt(j)) {
while((i+l)<str1.length()&&(j+l)<str2.length()&&str1.charAt(i+l)==str2.charAt(j+l)) {
l++;
}
}
}
ans=Math.max(ans, l);
}
System.out.println(str1.length()+str2.length()-2*ans);
}
}
}
}
F - Spy Detected! CodeForces - 1512A
题解:给出一个数组,然后找出数组中与其他数不一样的;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t=sc.nextInt();
while(t-->0) {
int n=sc.nextInt();
int a[]=new int[n];
int b[]=new int[101];
int x=0;
for(int i=0;i<n;i++) {
a[i]=sc.nextInt();
b[a[i]]++;
}
for(int i=0;i<n;i++) {
if(b[a[i]]==1) {
x=i;
break;
}
}
System.out.println(x+1);
}
}
}
G - The Great Hero CodeForces - 1480B
题目链接.
题解:有一个人和一群怪兽,然后人和这些怪兽打架,看打得过不。
然后就直接模拟。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int t=sc.nextInt();
while(t-->0) {
long aa=sc.nextLong();
long bb=sc.nextLong();
int sum=sc.nextInt();
long a[]=new long[sum];
long b[]=new long[sum];
for(int i=0;i<sum;i++) {
a[i]=sc.nextInt();
}
for(int i=0;i<sum;i++) {
b[i]=sc.nextInt();
}
long ans=-1;
long sum0=0;
for(int i=0;i<sum;i++) {
if(b[i]%aa==0) {
sum0+=(b[i]/aa)*a[i];
}else {
sum0+=(b[i]/aa+1)*a[i];
}
ans=Math.max(ans, a[i]);
}
if(sum0-ans>=bb) {
System.out.println("NO");
}else {
System.out.println("YES");
}
}
}
}
H - Ping-pong CodeForces - 1455C
直接模拟就好了
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t=sc.nextInt();
while(t-->0) {
int x=sc.nextInt();
int y=sc.nextInt();
System.out.println(x-1 + " " + y);
}
}
}
I - Increase and Copy CodeForces - 1426C
题目链接
题解:序列一开始是1,然后可以有两个操作,一个是+1,一个是复制数组最大的数。
可以一直增加到根号n,对勾函数
再1-根号n中进行遍历,找最少,
算次数不要忘记数组其他元素
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t=sc.nextInt();
while(t-->0) {
int n=sc.nextInt();
int x=(int) (Math.sqrt(n)+1);
int ans=Integer.MAX_VALUE;
for(int j=0;j<=x;j++) {
int now=1+j;
int num=(n-now+now-1)/now;
ans=Math.min(ans, num+j);
}
System.out.println(ans);
}
}
}
J - Split it! CodeForces - 1496A
题目链接
直接看首尾 k 个字符是否相同,同时得保证 n > k ∗ 2
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t=sc.nextInt();
while(t-->0) {
int n=sc.nextInt();
int k=sc.nextInt();
String str=sc.next();
boolean bool=false;
for(int i=0;i<k;i++) {
if(str.charAt(i)!=str.charAt(n-i-1)) {
bool=true;
break;
}
}
if(!bool&&k*2<n) {
System.out.println("YES");
}else {
System.out.println("NO");
}
}
}
}