Easy Problems

Simple Count

Description
For two \(1\)~\(n\), define \(a,b\), orz(a,b)=max(a_1, b_1)+\)... (+max(a_n, b_n)\).
You need to find out how many pairs \((a,b)\) satisfy \(orz(a,b)\; \geq\ m\).
Input
Two positive integers in a row\(n,m\).
Output
One integer per line represents the answer. Modeling (9944353).
Sample Input

3 8

Sample Output

18

HINT
\(1\;\leq\;n\;\leq\;50,1\;\leq\;m\;\leq\;2500\).
Solution

\(a_i=i\), \\\\\\\\\\\$i$, $j$j$of $j $$is filled in $1$\\\\\\\\\\\\\\\(a_i, b_i) =k\).

Fill i n \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\, put $i$i n $i+1$\(n,i\) for five cases:
\(f[i][j][k]=f[i-1][j-1][k-i]\)
\(\;\;\;\;\;\;\;\;\;\;\;\;\;\;+f[i-1][j-2][k-i\times2]\times[(i-1)-(j-2)]\)
\(\;\;\;\;\;\;\;\;\;\;\;\;\;\;+f[i-1][j-1][k-i]\times[(i-1)-(j-1)]\)
\(\;\;\;\;\;\;\;\;\;\;\;\;\;\;+f[i-1][j-1][k-i]\times[(i-1)-(j-1)]\)
\(\;\;\;\;\;\;\;\;\;\;\;\;\;\;+f[i-1][j][k]\)
The last \(\times\;n!\) is the answer.

#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 55
#define M 1901
#define K 998244353ll
using namespace std;
typedef long long ll;
int n,m,mx;
ll f[N][N][M],mul=1ll,ans;
inline ll sqr(int k){
	return (ll)(k*k);
}
inline void Aireen(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
		mul=mul*(ll)(i)%K;
	f[0][0][0]=1;
	for(int i=1;i<=n;++i)
		for(int j=0;j<=i;++j)
			for(int k=0;k<M;++k){
				if(j&&k>=i) f[i][j][k]=(f[i][j][k]+f[i-1][j-1][k-i])%K;
				if(j>=2&&k>=(i<<1)) f[i][j][k]=(f[i][j][k]+f[i-1][j-2][k-(i<<1)]*sqr(i-j+1)%K)%K;
				if(j&&k>=i) f[i][j][k]=(f[i][j][k]+f[i-1][j-1][k-i]*(ll)(i-j)%K)%K;
				if(j&&k>=i) f[i][j][k]=(f[i][j][k]+f[i-1][j-1][k-i]*(ll)(i-j)%K)%K;
				f[i][j][k]=(f[i][j][k]+f[i-1][j][k])%K;
			}
	for(int i=m;i<M;++i){
		ans=(ans+f[n][n][i]*mul)%K;
	}
	printf("%lld\n",ans); 
}
int main(){
	freopen("easycount.in","r",stdin);
	freopen("easycount.out","w",stdout);
	Aireen();
	fclose(stdin);
	fclose(stdout);
	return 0;
}

Simple geometry

Description
Given \(n\) white points and \(m\) black points, you need to find out how many neighboring points are heterochromatic
A convex quadrilateral. The coordinates of the point are integers in \([1,10^7]\). Ensure that there are no two points with the same coordinates and no three points collinear.
Input
The first line has two positive integers\ (n,m\).
Next \(n+m\) rows have two integers per row \(x,y\) representing coordinates. The front\(n\) behaves as white dots, and the back\(m\) behaves as black dots.
Output
One integer per line represents the answer.
Sample Input

5 5
7612781 7923905
390883 6554981
8816160 3805981
4131888 3855473
4491640 5239819
998553 2850237
5957016 3387077
8511547 701391
8935990 677435
3706758 5650977

Sample Output

18

HINT
\(n,m\;\leq\;400\).
Solution
Number of quadrilateral with heterochromatic neighboring points - Number of concave quadrilateral with heterochromatic neighboring points.
Number of quadrilateral with heterochromatic adjacent points: Number of black dots on one side of the line where two white dots are located\(\times\) and black dots on the other side.
Number of concave quadrilateral with heterochromatic adjacent points: enumerate white points and enumerate two more black points, in which case the white points in the area \(1\) in the diagram will form a concave quadrilateral with them. After enumerating white points, the reverse extension lines connecting each black point to this white point and the lines connecting other white points to this white point will be sorted by polar angles, and the addition and subtraction, prefix and solution will be discussed. (Angle spans of extension lines do not cross vectors with polar angle\(0\)

#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 405
#define eps 1e-13
using namespace std;
typedef long long ll;
const double pi=acos(-1);
struct point{
	int x,y;
}a[N],b[N];
struct cnt{
	int s;double w;
}p[N+N]; 
int n,m,sum;ll ans;
inline bool cmp(cnt x,cnt y){
	return x.w<y.w;
}
inline point dec(point x,point y){
	return (point){x.x-y.x,x.y-y.y};
}
inline int mul(point x,point y){
	ll k=(ll)(x.x)*(ll)(y.y)-(ll)(y.x)*(ll)(x.y);
	if(!k) return 0;
	if(k<0ll) return -1;
	return 1;
}
inline void Aireen(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
		scanf("%d%d",&a[i].x,&a[i].y);
	for(int i=1;i<=m;++i)
		scanf("%d%d",&b[i].x,&b[i].y);
	for(int i=1;i<n;++i)
		for(int j=i+1;j<=n;++j){
			sum=0;
			for(int k=1;k<=m;++k)
				if(mul(dec(b[k],a[i]),dec(a[j],a[i]))>0) ++sum;
			ans+=(ll)(sum*(m-sum));
		}
	for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j){
			p[j].w=atan2(b[j].y-a[i].y,b[j].x-a[i].x);
			if(p[j].w>0.0) p[j].w-=pi;
			else p[j].w+=pi;
		}
		sort(p+1,p+1+m,cmp);
		for(int j=1;j<=m;++j){
			p[j].s=0;
			for(int k=1;k<j;++k)
				if(p[j].w-p[k].w<pi) ++p[j].s;
				else{
					--p[j].s;ans-=(ll)(n-1);
				} 
			for(int k=j+1;k<=m;++k)
				if(p[k].w-p[j].w<pi) --p[j].s;
				else ++p[j].s;
		}
		for(int j=1;j<i;++j){
			p[j+m].s=N;p[j+m].w=atan2(a[j].y-a[i].y,a[j].x-a[i].x);
		}
		for(int j=i+1;j<=n;++j){
			p[j+m-1].s=N;p[j+m-1].w=atan2(a[j].y-a[i].y,a[j].x-a[i].x);
		}
		sort(p+1,p+m+n,cmp);sum=0;
		for(int j=1;j<n+m;++j){
			if(p[j].s==N) ++sum;
			else ans-=(ll)(sum*p[j].s);
		}
	}
	printf("%lld\n",ans);
}
int main(){
	freopen("easygeom.in","r",stdin);
	freopen("easygeom.out","w",stdout);
	Aireen();
	fclose(stdin);
	fclose(stdout);
	return 0;
}

Simple 01 Series

Description
Given a \(01\) string of length \(n\) and a positive integer \(m\).
You can do two things:

  1. Reverse a bit of the string;
  2. Reverse the \(01\) bit before the \(k\;;\times\; m\) string (\(k\) is an integer and \(0<k\;; \times\m\;; \leq\n\))

You need to find out how many operations you need to do at least to make the first \(01\) bit of this string the same as the last n-m bit.
Input
The first row has two integers \(n,m\).
The second line is a \(01\) string of length \(n\).
Output
One integer per line represents the answer.
Sample Input

12 3
010011001101

Sample Output

3

HINT
\(n\;\leq\;300,m\;\leq\;55\).
Solution
The meaning of the title is equivalent to the minimum number of steps required to make the \(01\) string a loop per \(m\).
Obviously, the complexity of O(n\times2^{\sqrt{n}})\) is acceptable.
There are two cases:
\(1.m\leq\sqrt{n},\) enumerates the \(01\) strings of the cyclic sections, \(DP\) gives the minimum number of changes required for each segment, \(f[i][0/1]\) whether the preceding \(i\) segment takes the minimum number of steps required to reverse, and does not have a direct judgement of the paragraph \(m\).
\(k\) denotes the number of changes required for an unmarried couple.
\(f[i][0]=min(f[i-1][0],f[i-1][1])+k,\)
\(f[i][1]=min(f[i-1][0]+min(2,(i-1)m),f[i-1][1])+m-k\).
\(2.m>\sqrt{n}\) enumerates whether each paragraph is reversed, and the same bit becomes the same minimum number of changes required.

#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 305
using namespace std;
typedef long long ll;
int f[N][2],g[N],a[N],b[N],n,m,sum,ans,cnt;
bool flag;char ch[N];
inline void dfs2(int u,int s,int f){
	if(u<0){
		int cnt=0;
		for(int i=0,k,l=n-n%m;i<m;++i){
			k=0;flag=false;
			for(int j=i;j<n;j+=m){
				if(j>=l) flag=true;
				if(a[j]^g[j/m]) ++k;
			}
			if(flag) cnt+=min(n/m+1-k,k);
			else cnt+=min(n/m-k,k);
		}
		ans=min(ans,cnt+s);
		return;
	}
	g[u/m]=f;
	dfs2(u-m,s,f);
	g[u/m]=f^1;
	dfs2(u-m,s+1,f^1);
}
inline void dfs1(int u){
	if(u==m){
		int cnt=0;
		memset(g,0,sizeof(g));
		for(int l=0,j;l<n;l+=m){
			j=l/m;
			for(int i=l;i<l+m&&i<n;++i)
				if(a[i]!=b[i%m]) ++g[j];
			if(n-l<m){
				cnt=min(n%m-g[j],g[j]);
			} 
			else if(!l){
				f[l][0]=g[j];f[l][1]=m-g[j]+1;
			}
			else{
				f[j][0]=min(f[j-1][0],f[j-1][1])+g[j];
				f[j][1]=min(f[j-1][0]+min(2,l),f[j-1][1])+m-g[j];
			}
		}
		ans=min(ans,min(f[(n-n%m-1)/m][0],f[(n-n%m-1)/m][1])+cnt); 
		return;
	}
	b[u]=0;dfs1(u+1);
	b[u]=1;dfs1(u+1);
}
inline void Aireen(){
	scanf("%d%d",&n,&m);
	scanf("%s",ch);
	for(int i=0;i<n;++i){
		a[i]=ch[i]-'0';
		if(a[i]) ++ans;
	}
	ans=min(ans,n-ans);
	if(m<=17) dfs1(0);
	else dfs2(n-n%m,0,0);
	printf("%d\n",ans);
}
int main(){
	freopen("easy01.in","r",stdin);
	freopen("easy01.out","w",stdout);
	Aireen();
	fclose(stdin);
	fclose(stdout);
	return 0;
}

2017-01-26 19:18:31

Tags: greedy algorithm dp

Posted on Wed, 24 Nov 2021 13:44:55 -0500 by pwes24