ACM winter holiday happy competition question solution

Competition website

https://vjudge.net/contest/350953

First of all: due to the sudden death of cfcf, the experience is extremely poor. When cfcf survives, we can see the result of submission (who wants to know, yesterday was still alive)

A.1228

Original question link:

https://codeforces.com/problemset/problem/1228/A

Title:

Given an interval of 1 ≤ l ≤ r ≤ 1051\leq l \leq r \leq 10^51 ≤ l ≤ r ≤ 105), let you take any number xxx in the interval. It is required that each digit of xxx is different. If there is no such number, output − 1-1 − 1.

Train of thought:

Violent judgment is enough.

Scale:

#include <bits/stdc++.h>
using namespace std;
int main() {
  int l, r;
  scanf("%d%d", &l, &r);
  for (int i = l; i <= r; ++i) {
    int book[15] = {0}, temp = i, flag = 0;
    while (temp) {
      book[temp % 10]++;
      if (book[temp % 10] == 2) {
        flag = 1;
        break;
      }
      temp /= 10;
    }
    if (!flag)
      return !printf("%d\n", i);
  }
  return !printf("-1\n");
}

B.1118

Original question link:

https://codeforces.com/contest/1118/problem/B

Title:

In this paper, we give nnn numbers, and ask how many sum of odd and even positions of the remaining numbers are equal after deleting one number in turn.

Train of thought:

If the third digit is deleted, the parity before the third digit is the same, and the parity after the third digit is the opposite of the original, so we use the prefix sum to find the prefix on the odd position and the prefix sum on the even position respectively, and then if the third digit is deleted, we will judge the odd prefix of the first I − 1i-1i − 1 digit and the prefix of the last even digit Whether the sum of the infixes is equal to the even prefix of the first I − 1i-1i − 1 bit and the sum of the prefixes of the odd positions after it.

Scale:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5 + 10;
int a[N], odd[N], even[N];
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
  }
  odd[1] = a[1];
  even[1] = 0;
  for (int i = 2; i <= n; i++) {
    if (i & 1) {
      odd[i] = a[i] + odd[i - 1];
      even[i] = even[i - 1];
    } else {
      odd[i] = odd[i - 1];
      even[i] = even[i - 1] + a[i];
    }
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    if (odd[i - 1] + even[n] - even[i] == even[i - 1] + odd[n] - odd[i]) {
      ans++;
    }
  }
  printf("%d\n", ans);
  return 0;
}

C.1559

Original question link:

http://acm.hdu.edu.cn/showproblem.php?pid=1559

Title:

Let's give you an integer matrix of m × nm × nm × n, and find a submatrix of x × yx × yx × y on it, so that the sum of all elements in the submatrix is the largest.

Train of thought;

Preprocess the two-dimensional prefix and then O(1)O(1)O(1) query.

Scale:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e3 + 5;
const int inf = 0x3f3f3f3f;
ll a[N][N];
int main() {
  int t, m, n, x, y;
  ll ans;
  scanf("%d", &t);
  while (t--) {
    ans = -inf;
    scanf("%d%d%d%d", &n, &m, &x, &y);
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= m; j++) {
        scanf("%lld", &a[i][j]);
        a[i][j] = a[i][j] + a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];
      }
    }
    //From i, j to i+x-1, j+y-1
    for (int i = 1; i <= m - x + 1; i++) {
      for (int j = 1; j <= n - y + 1; j++) {
        ans = max(ans, a[i + x - 1][j + y - 1] - a[i + x - 1][j - 1] - a[i - 1][j + y - 1] + a[i - 1][j - 1]);
      }
    }
    printf("%lld\n", ans);
  }
  return 0;
}

D.2456

Original question link:

http://poj.org/problem?id=2456

Title:

There are nnn places, there are mmm cattle, and only one place can be allocated to a cow. Ask how to allocate the maximum value that makes the distance between all cattle the smallest, and what is it.

Train of thought:

To find the maximum value of the minimum value, first rank the positions of the compartments. The maximum value of the minimum value between compartments is the position of the last compartment minus the position of the first compartment. In this way, we can divide it into two parts. When we judge the minimum distance between each two cows, whether we can install ccc cows or not, how to judge is also a noteworthy place. We must make the first compartment Put a cow in the position between the two, greedy thinking, and then judge whether the distance between the position of the next compartment and the position of the previous cowherd is greater than or equal to midmidmid midmid. If it meets the conditions, put it in, and change the position of the previous cowherd to the current position.

Scale:

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int a[N];
int n,m;
int judge(int x) {
	int num=1;
	int pos=a[1];
	for(int i=2; i<=n; i++) {
		if(a[i]-pos>=x) {
			num++;
			pos=a[i];
		}
	}
	return num>=m;
}
int main() {
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++) {
		scanf("%d",&a[i]);
	}
	sort(a+1,a+1+n);
	int l=0,r=1e9;
	int ans;
	while(l<=r) {
		int mid=(l+r)/2;
		if(judge(mid)) {
			l=mid+1;
			ans=mid;
		} else {
			r=mid-1;
		}
	}
	printf("%d\n",ans);
	return 0;
}

E.1988

Original question link:

http://poj.org/problem?id=1988

Title:

Given NNN blocks, line them up and number them 111 to NNN. Then PPP operations are given:

① Mmm i I i j j j means to move the pile of i to the top of the pile of J.

② CCC iii means a query, asking how many squares are under iii.

Train of thought:

Take the weight and look up the set. The top block in a pile is the parent node. Use dis[X]dis[X]dis[X] to count the distance from X to the parent node. num[fa[X]]num[fa[X]]num[fa[X]] denotes the size of the set. Subtraction of the two is the answer.

Scale:

#include <bits/stdc++.h>
using namespace std;

#define ll long long
const int inf = 0x3f3f3f3f;
const int N = 300010;
const double pi = acos(-1.0);

int pre[N],num[N],dis[N];
int n;

void init() {
	for(int i=0; i<n; i++) {
		pre[i]=i;
		num[i]=1;
		dis[i]=0;
	}
}
int Find(int x) {
	if(x!=pre[x]) {
		int t=pre[x];
		pre[x]=Find(pre[x]);
		dis[x]+=dis[t];
	}
	return pre[x];
}

int main() {
	while(~scanf("%d",&n)) {
		init();
		char op;
		while(n--) {
			scanf(" %c",&op);
			int x,y;
			if(op=='M') {
				scanf("%d %d",&x,&y);
				int fx=Find(x);
				int fy=Find(y);
				if(fx!=fy) {
					pre[fy]=fx;
					dis[fy]=num[fx];
					num[fx]+=num[fy];
				}
			} else {
				scanf("%d",&x);
				int fx=Find(x);
				printf("%d\n",num[fx]-dis[x]-1);
			}
		}
	}
	return 0;
}

F.1421

Original question link:

http://acm.hdu.edu.cn/showproblem.php?pid=1421

Title:

Select k logarithm (i.e. 2 * k2*k2 * k) from n n n (n ≤ 2000n \leq 2000n ≤ 2000) to minimize the sum of squares of their differences.

Train of thought:

Obviously, if you want to minimize fatigue, you must select the weight adjacent to each other, so you need to rank all the items by weight

dp[i][j] means dp[i][j] means dp[i][j] means dp[i][j] means there are three articles, from which the minimum possible fatigue degree of jjj for articles can be selected. Obviously, this state can only come from dp[i − 1][j]dp[i − 1][j]dp[i − 1][j] and dp[i − 2][j − 1]dp[i-2][j-1]dp[i − 2][j − 1] respectively.

The equation of state transition is:

dp[i][j]=min(dp[i−1][j],dp[i−2][j−1]+(a[i−1]−a[i−2])∗(a[i−1]−a[i−2]))dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+(a[i-1]-a[i-2])*(a[i-1]-a[i-2]))dp[i][j]=min(dp[i−1][j],dp[i−2][j−1]+(a[i−1]−a[i−2])∗(a[i−1]−a[i−2]))

i:2 − > n i:2 - > Ni: 2 − > N, j: 1 − > k and J ≤ ij: 1 - > k and j \leq ij: 1 − > k and J ≤ I

Scale:

#include<bits/stdc++.h>
using namespace std;
const int inf = 0xfffffff;
const int N = 2e3+10;
int a[N],dp[N][N];
int main() {
	int n,k;
	while(cin>>n>>k) {
		for(int i=0; i<n; i++) {
			cin >> a[i];
		}
		for(int i=0; i<=n; i++) {

			for(int j=0; j<=k; j++) {
				j == 0 ? dp[i][j] = 0 :dp[i][j] = inf;
			}
		}
		sort(a,a+n);
		for(int i=2; i<=n; i++) {
			for(int j=1; j<=k&&j<=i; j++) {
				dp[i][j] = min(dp[i-1][j], dp[i-2][j-1] + (a[i-1]-a[i-2])*(a[i-1]-a[i-2]));
			}
			cout << dp[n][k] << endl;
		}
	}
	return 0;
}

G.1376

Original question link:

http://poj.org/problem?id=1376

Title:

Given the map, start point, end point and initial direction, each operation from the start point can advance 1-3 grid to the current direction or rotate 90 degrees to change the direction. It needs at least several operations to reach the end point.

Train of thought;

And the robots are There's a radius, so it's impossible to walk to the boundary, and then bfsbfsbfs will do. Note that you can walk 1 − 31-31 − 3 spaces at a time.

Scale:

#include<stdio.h>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;
struct note {
	int x,y,id,s;
	bool operator == (const note &a) const {
		return a.y==y&&a.x==x;
	}
} st,ed;
int vis[100][100][10];
int mp[100][100];
int n,m;
int dir[4][2]= {0,1,1,0,0,-1,-1,0};
int check(int x,int y,int id) {
	if(x>0&&y>0&&x<n&&y<m&&vis[x][y][id]==0)
		return 1;
	return 0;
}
int bfs() {
	queue<note>Q;
	memset(vis,0,sizeof(vis));
	st.s=0;
	Q.push(st);
	note now,temp;
	while(!Q.empty()) {
		now=Q.front();
		Q.pop();
		if(now==ed) {
			printf("%d\n",now.s);
			return 1;
		}

		temp=now;
		temp.s++;
		temp.id=(temp.id+1)%4;
		if(vis[temp.x][temp.y][temp.id]==0) {
			vis[temp.x][temp.y][temp.id]=1;
			Q.push(temp);
		}
		temp=now;
		temp.s++;
		temp.id=(temp.id-1+4)%4;
		if(vis[temp.x][temp.y][temp.id]==0) {
			vis[temp.x][temp.y][temp.id]=1;
			Q.push(temp);
		}

		for(int i=1; i<=3; i++) {
			temp=now;
			temp.x=now.x+dir[temp.id][0]*i;
			temp.y=now.y+dir[temp.id][1]*i;
			if(mp[temp.x][temp.y]==1)break;
			if(check(temp.x,temp.y,temp.id)) {
				temp.s++;
				vis[temp.x][temp.y][temp.id]=1;
				Q.push(temp);
			}
		}
	}
	return 0;
}
int main() {
	while(~scanf("%d%d",&n,&m)&&(n+m)) {
		int t;
		memset(mp,0,sizeof(mp));
		for(int i=0; i<n; i++) {
			for(int j=0; j<m; j++) {
				scanf("%d",&t);
				if(t==1) {
					mp[i][j]=mp[i+1][j]=mp[i][j+1]=1;
					mp[i+1][j+1]=1;
				}
			}
		}
		scanf("%d%d%d%d",&st.x,&st.y,&ed.x,&ed.y);
		char mp[20];
		scanf("%s",mp);
		if(mp[0]=='s')
			st.id=1;
		else if(mp[0]=='e')
			st.id=0;
		else if(mp[0]=='w')
			st.id=2;
		else
			st.id=3;
		if(bfs()==0)
			printf("-1\n");
	}
	return 0;
}

H.6221

Original question link:

https://codeforces.com/problemset/problem/622/A

Title:

Let's find the number nnn in this row.

Train of thought:

The n n n position belongs to 111 to k k k, find kkk, and then n − k * (K − 1) 2n-\frac{k * (k-1)} {2}n − 2k * (K − 1) is the answer.

Method 1: we can enumerate kkk as I I I. When I * (i-1) 2\frac{i * (i-1)} {2}2i * (i-1) is greater than or equal to nnn, kkk is iii.

Method 2: let k=floor(sqrt(2 * n))k=floor(sqrt(2*n))k=floor(sqrt(2 * n)), if k * (K − 1) 2 < n \ frac {k * (k-1)} {2} < n 2K * (K − 1) < n, then the correct kkk should be + 1 + 1 + 1.

Scale:

  • Method 111
#include <cstdio>
typedef long long ll;
int main() {
	ll n,k=1;
	scanf("%lld",&n);
	while(k) {
		if(k*(k+1)/2>=n)break;
		k++;
	}
	printf("%lld\n",n-k*(k-1)/2);
	return 0;
}
  • Method 222
#include<cstdio>
#include<cmath>
typedef long long ll;
int main() {
	ll n,k;
	scanf("%lld",&n);
	k=floor(sqrt(2*n));
	if (k*(k+1)/2<n)k++;
	printf("%lld",n-k*(k-1)/2);
	return 0;
}

I.1263

Original question link:

https://codeforces.com/problemset/problem/1263/C

Title:

To give an n n n, let you find the value of any number \ frac{n} {any number} any number n which can be rounded down.

Train of thought:

N n n has 1e91e91e9, so we must not timeout violent enumeration, but the array will not be saved. Here we will find a rule that when enumeration i is ni\frac{n}{i}in the same value as ni − 1\frac{n}{i-1}i − 1n, all the following values from 0 to n i 0 to \ frac{n}{i}0 to in will exist.

Scale:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e7;
int ans[N];
int main() {
	int T;
	scanf("%d",&T);
	while(T--) {
		ll n;
		scanf("%lld",&n);
		int cut=0;
		for(int l=1,r; l<=n; l=r+1) {
			r=n/(n/l);
			ans[cut++]=n/l;
		}
		ans[cut++]=0;
		printf("%d\n",cut);
		sort(ans,ans+cut);
		for(int i=0; i<cut; ++i) {
			printf("%d ",ans[i]);
		}
		printf("\n");
	}
	return 0;
}

J.1278

Original question link:

https://codeforces.com/problemset/problem/1278/B

Title:

For t(1 ≤ t ≤ 100)t(1 \leq t \leq 100)t(1 ≤ t ≤ 100) test points, give two numbers aaa and bbb, and do the following operations:

In step iii, you can choose a number plus iii and ask how many steps at least you can make two numbers equal.

Train of thought;

Assume xxx operations. Then we need to guarantee $\ frac {(x + 1) * x} {2} \ Leq ABS (a-b) $.

Suppose a, ba, ba, b are added to Y Y Y and a+b+(x+1) * x2a+b+\frac{(x+1)*x}{2}a+b+2(x+1) * x = = 2 * y2*y2 * y.

It should be an even number when B B B should add (a+b+(x+1) * x2)/2 − b(a+b+\frac{(x+1)*x}{2})/2-b(a+b+2(x+1) * x) / 2 − b=((x+1) * x2+a − b)/2(\frac{(x+1)*x}{2}+a-b)/2(2(x+1) * x + a − b)/2.
In this case, we only need to guarantee that the solution is even (x+1) * x2+a − b\frac{(x+1)*x}{2}+a-b2(x+1) * x + a − B. Because a+ba+ba+b and a − ba-ba − B have the same parity, we only need to satisfy $abs(a-b)\leq \frac{(x+1)*x}{2}, and, and \ frac{(x+1)*x}{2} +a+b $are even numbers, so we only need to traverse xxx from 000 to meet the conditions to output the answer.

Scale:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
	int T;
	scanf("%d",&T);
	while(T--) {
		ll a,b;
		scanf("%lld%lld",&a,&b);
		for(ll i=0;; i++) {
			ll temp=(i+1)*i/2;
			if(temp>=abs(a-b)&&(a+b+temp)%2==0) {
				printf("%lld\n",i);
				break;

			}
		}
	}
	return 0;
}

Once again, this competition is a happy winter holiday competition, which aims to improve everyone's interest in writing questions and urge everyone to learn, without affecting everyone's normal training.

Published 294 original articles, praised 212, visited 110000+
Private letter follow

Tags: PHP

Posted on Sat, 11 Jan 2020 08:20:32 -0500 by spectsteve7