Educational Codeforces Round 89 (A-D)

Educational Codeforces Round 89 (A-D)

比賽沒打,來補題辣。

A. Shovels and Swords

思路:數學,高中線性規劃搞一下,由於a,ba,b對稱性,可以默認aba\leq b,然後分兩種情況搞一下就行了。

ans={a+b3,b2aa        ,otherwiseans=\begin{cases}\dfrac{a+b}{3},b\leq2a\\a\ \ \ \ \ \ \ \ ,otherwise\end{cases}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
int main(){
	int t;
	cin>>t;
	while(t--){
		int a,b;
		cin>>a>>b;
		if(a>b) swap(a,b); 
		if(b<=2*a) cout<<(a+b)/3<<endl;
		else cout<<a<<endl;
	} 
	return 0;
}

B. Shuffle

思路:簡單貪心,找到一個含xx的區間,然後不斷更新區間長度即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
int main(){
	int t;
	cin>>t;
	while(t--){
		int n,x,m;
		cin>>n>>x>>m;
		int L=0,R=0,f=0;
		for(int i=1;i<=m;i++){
			int l,r;
			cin>>l>>r;
			if((x>=l&&x<=r)&&!f){
				 L=l,R=r,f=1;
				 continue;	
			}
			if(f){
				if(l>R||r<L) continue;
				else L=min(L,l),R=max(R,r);
			}			
		}
		cout<<R-L+1<<endl;
	} 
	return 0;
}

C. Palindromic Paths

思路:貪心,因爲是迴文串,所以走kk步的點要與走n+m2kn+m-2-k步的點相同,

簡單證明一下:

(101111101101101111101)\begin{pmatrix} 1 & 0 & 1 & 1 & 1 & 1 & 1\\ 0 & 1 & 1 & 0 & 1 & 1 & 0\\ 1 & 1 & 1 & 1 & 1 & 0 & 1 \end{pmatrix}

比如走兩步的點有(1,3),(2,2),(3,1)(1,3),(2,2),(3,1),走n+m22=6n+m-2-2=6步的點有:

(1,7),(2,6),(3,5)(1,7),(2,6),(3,5).

顯然可以從(3,1)(3,5).(3,1)走到(3,5).所以num[3][1]=num[3][5]num[3][1]=num[3][5]. (1)

同理:(2,2)(2,6),(3,5)num[2][2]=num[2][6]=num[3][5](2,2)可以走到(2,6),(3,5) \rightarrow num[2][2]=num[2][6]=num[3][5]. (2)

(1,3)(1,7),(2,6),(3,5)num[1][3]=num[1][7]=num[2][6]=num[3][5](3)(1,3)可以走到(1,7),(2,6),(3,5)\\ \Rightarrow num[1][3]=num[1][7]=num[2][6]=num[3][5] \quad(3)

聯立(1),(2),(3)(1),(2),(3)可以知道所有數要相等。

然後每步貪心判斷一下選0還是1即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=65;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
int a[N][2];
int main(){
	int t;
	cin>>t;
	while(t--){
		int n,m;
		cin>>n>>m;
		mst(a);
		for(int i=1;i<=n;i++)
			for(int j=1,x;j<=m;j++){
				 cin>>x;
				 a[i+j-2][x]++;
			}
		int ans=0;
		for(int i=0,j=n+m-2;i<j;i++,j--)
			ans+=min(a[i][0]+a[j][0],a[i][1]+a[j][1]);
		printf("%d\n",ans);
	} 
	return 0;
}

D. Two Divisors

思路:數論知識,

若兩質數(p,q)=1(pk1,qk2)=(pk1+qk2,pk1)=(pk1+qk2,qk2)=(pk1+qk2,pk1×qk2)=1,(k1,k2)(p,q)=1\rightarrow(p^{k_1},q^{k_2})\\=(p^{k_1}+q^{k_2},p^{k_1})\\=(p^{k_1}+q^{k_2},q^{k_2})\\=(p^{k_1}+q^{k_2},p^{k_1}\times q^{k_2})=1,(k1,k2爲正整數).

若數xx只有一個質因子,說明它的因數都是pp的倍數,即gcd最大爲pk>1p^k>1
所以對數xx進行質因數分解:得到p1k1×pmkm=xp_1^{k_1}\times\dots p_m^{k_m}=x.

(p1k1pm1km1+pmkm,pmkm)=1(p_1^{k_1}\dots p_{m-1}^{k_{m-1}}+p_m^{k_m},p_m^{k_m})=1

這裏取pmp_m是爲了加速質因數分解。

所以進行素數篩預處理一下,然後判斷因子是否爲1即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+10,M=1e7+5;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
inline void read(int &x){ 
	x=0;int w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
	for(;ch>='0'&&ch<='9';ch=getchar())
		x=(x<<3)+(x<<1)+(ch&15);
	x*=w; 
}
int p[M];
PII ans[N];
void fun(){
	int n=1e7;
	for(int i=2;i<=n;i++)
		 if(!p[i])
			for(int j=i;j<=n;j+=i) p[j]=i;
}
int main(){
	int n;
	fun();
	read(n);
	for(int i=1,x;i<=n;i++){
		 read(x);
		 int a=p[x],y=1;
		 while(x%a==0){
		 	 x/=a,y*=a;
		 }
		 if(x==1) x=y=-1;
		 ans[i]={x,y};
	}
	for(int i=1;i<=n;i++) printf("%d ",ans[i].fi);
	puts("");
	for(int i=1;i<=n;i++) printf("%d ",ans[i].se);
	return 0;
}

待補\dots\dots

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章