Educational Codeforces Round 89 (Rated for Div. 2) 补题报告A.数学/贪心 B.思维 C.思维 D.唯一分解定理+gcd性质

8 篇文章 0 订阅
3 篇文章 0 订阅

感冒了没写Orz,只补了一部分。

A - Shovels and Swords(数学/好像贪心也行)

虽然感觉贪心也行,但是写起来好像不是很容易。。。联想到动态规划应该还是可以的(高中的没忘的话)。
设两个物品为A、B,分别制作了x件、y件,则满足不等式
2 x + y < = a 2x+y<=a 2x+y<=a
x + 2 ∗ y < = b x+2*y<=b x+2y<=b
目标函数z=x+y
按照高中老师教的,画个图,带交点就能求出来了。但还要考虑下两条直线再第一象限没交点的情况,那就代端点。

#include <iostream>
#include <map>
#include <ctime>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset> 
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
//#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
    if(x<0)
    {
        putchar('-');
        x=-x;
    }
    if(x>9)
    {
        write(x/10);
    }
    putchar(x%10+'0');
}
 
template<typename T> void read(T &x)
{
    x = 0;char ch = getchar();ll f = 1;
    while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
    while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//¿´ÊÇ·ñÒªmod 
	ll ans=1;
	while(n){
		if(n&1) ans=(ans*a)%mod;
		a=a*a%mod;
		n>>=1;
	}
	return ans%mod;
}
//==============================================================
int t;
ll a,b;

int main()
{
	#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
	#endif
	//===========================================================
	read(t);
    while(t--){
        cin>>a>>b;
        ll ans=min((a+b)/3,min(a,b));
        write(ans);
        putchar('\n');
    }
	//===========================================================
	return 0;
}

B - Shuffle CodeForces - 1366B(思维)

看题看错愣了一会。。
因为它没有规定c、能不能相等,所以,1移动到一个位置之后,其实就可以永远不动了,因此,我们只需要判断下给出的l和r区间是否和现在1可能存在的区间有交集,有的话,就取个并集作为新的1可能存在的区间,1可能存在的区间一开始是 [ x , x ] [x,x] [x,x]这个区间。

#include <iostream>
#include <map>
#include <ctime>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset> 
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
    if(x<0)
    {
        putchar('-');
        x=-x;
    }
    if(x>9)
    {
        write(x/10);
    }
    putchar(x%10+'0');
}
 
template<typename T> void read(T &x)
{
    x = 0;char ch = getchar();ll f = 1;
    while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
    while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//¿´ÊÇ·ñÒªmod 
	ll ans=1;
	while(n){
		if(n&1) ans=(ans*a)%mod;
		a=a*a%mod;
		n>>=1;
	}
	return ans%mod;
}
//==============================================================
int t;
int n,x,m;


int main()
{
	#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
	#endif
	//===========================================================
	read(t);
    while(t--){
        cin>>n>>x>>m;
        int p1=x,p2=x;
        rep(i,1,m){
            int l,r;
            cin>>l>>r;
            if((l<=p2&&r>=p2)||(l<=p1&&r>=p1)){
                p2=max(r,p2);
                p1=min(l,p1);
            }
        }
        write(p2-p1+1),putchar('\n');
    }
	//===========================================================
	return 0;
}

C - Palindromic Paths(思维)

这里利用的是一个性质:若这个图为题目要求的,那么,和起点曼哈顿距离为i的点,和与终点的曼哈顿距离为i的点( i < ( n + m − 2 ) / 2 i<(n+m-2)/2 i<(n+m2)/2,避免重复,并且中间的i==(n+m-2)/2不需要,因为他们是回文路径的中间,没有点和他们配对),这两种点要么全都是1,要么全都是0,开个数组遍历一遍图,按照曼哈顿距离记录下,最后取个min就好了。

#include <iostream>
#include <map>
#include <ctime>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset> 
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
    if(x<0)
    {
        putchar('-');
        x=-x;
    }
    if(x>9)
    {
        write(x/10);
    }
    putchar(x%10+'0');
}
 
template<typename T> void read(T &x)
{
    x = 0;char ch = getchar();ll f = 1;
    while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
    while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//¿´ÊÇ·ñÒªmod 
	ll ans=1;
	while(n){
		if(n&1) ans=(ans*a)%mod;
		a=a*a%mod;
		n>>=1;
	}
	return ans%mod;
}
//==============================================================
int t,n,m;
int mp[50][50];
int save[100][2];
int save2[100][2];

int main()
{
	#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
	#endif
	//===========================================================
	read(t);
    while(t--){
        memset(save,0,sizeof(save));
        memset(save2,0,sizeof(save2));
        read(n),read(m);
        rep(i,1,n){
            rep(j,1,m){
                read(mp[i][j]);
            }
        }
        rep(i,1,n){
            rep(j,1,m){
                int dis=i+j-2;
                save[dis][mp[i][j]]++;
                int dis2=n+m-i-j;
                save2[dis2][mp[i][j]]++;

            }
        }
        ll ans=0;
        int maxdis=n+m-2;
        for(int i=0;2*i<maxdis;i++){
            ans+=min(save[i][0]+save2[i][0],save[i][1]+save2[i][1]);
        }
        write(ans),putchar('\n');
    }
	//===========================================================
	return 0;
}

D - Two Divisors(唯一分解定理+gcd性质)

数论弱鸡……
1)、根据唯一分解定理,任何一个数都可以分解为:
a i = p 1 q 1 ∗ p 2 q 2 ∗ p 3 q 3 ∗ … … p n q n a_i=p_1^{q_1}*p_2^{q_2}*p_3^{q_3}*……p_n^{q_n} ai=p1q1p2q2p3q3pnqn
2)、gcd性质:
g c d ( a , b ) = = 1 gcd(a,b)==1 gcd(a,b)==1(a、b互质),则: g c d ( a + b , a ∗ b ) gcd(a+b,a*b) gcd(a+b,ab)也互质。
原因是两个gcd的性质:
g c d ( a , b ) = g c d ( a + m b , a ) gcd(a,b)=gcd(a+mb,a) gcd(a,b)=gcd(a+mb,a)(m为任意整数)。
g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1,则 g c d ( a , b c ) = g c d ( a , b ) gcd(a,bc)=gcd(a,b) gcd(a,bc)=gcd(a,b)
按照上面的定理2,可以考虑把ai分解为两个数d1,d2,使得d1*d2=ai。要保证d1、d2互质,则让他们都是不同质数的倍数就行了。根据定理1,我们把ai分解为 d 1 = p 1 q 1 d1=p_1^{q_1} d1=p1q1 d 2 = p 2 q 2 ∗ p 3 q 3 ∗ … … p n q n d2=p_2^{q_2}*p_3^{q_3}*……p_n^{q_n} d2=p2q2p3q3pnqn两部分即可。

#include <iostream>
#include <map>
#include <ctime>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset> 
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
    if(x<0)
    {
        putchar('-');
        x=-x;
    }
    if(x>9)
    {
        write(x/10);
    }
    putchar(x%10+'0');
}
 
template<typename T> void read(T &x)
{
    x = 0;char ch = getchar();ll f = 1;
    while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
    while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//看是否要mod 
	ll ans=1;
	while(n){
		if(n&1) ans=(ans*a)%mod;
		a=a*a%mod;
		n>>=1;
	}
	return ans%mod;
}
//==============================================================
const int maxn=5e5+10;
int n;
int a[maxn];
int vis[(int)1e7+10];
vector<int> primes;
void init(){
    rep(i,2,(int)1e7+10-1){
        if(!vis[i]) primes.push_back(i);
        for(register int j=0;j<primes.size()&&i*primes[j]<(int)1e7+10;j++){
            vis[i*primes[j]]=1;
            if(i%primes[j]==0) break;
        } 
    }
}
int solve(int x){
    rep(i,0,primes.size()-1){
        if(primes[i]*primes[i]>x) break;
        if(x%primes[i]==0){
            int t=1;
            while(x%primes[i]==0){
                t*=primes[i];
                x/=primes[i];
            }
            if(x==1) break;
            else{
                return t;
            }
        }
    }
    return -1;
}
int save[maxn][2];
int main()
{
	#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
	#endif
	//===========================================================
	read(n);
    init();
    rep(i,1,n){
        read(a[i]);
    }
    rep(i,1,n){
        int ans=solve(a[i]);
        if(ans==-1){
            save[i][0]=-1,save[i][1]=-1;
        }
        else{
            save[i][0]=ans,save[i][1]=a[i]/ans;
        }
        vis[a[i]]=save[i][0];
    }
    rep(i,1,n){
        if(i-1) putchar(' ');
        write(save[i][0]);
    }
    putchar('\n');
    rep(i,1,n){
        if(i-1) putchar(' ');
        write(save[i][1]);
    }
	//===========================================================
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值