2017 ICPCECPC 邀请赛 F,D,E, I 题解


F-

问题 F: Teacher’s Day

时间限制: 1 Sec  内存限制: 128 MB
提交: 64  解决: 11
[提交][状态][讨论版]

题目描述

Teacher’s Day is coming, a group of n students decided to buy gifts.
The store offered them M gifts. The price is different for different gifts, buying the j-th gift costs pj yuan.
In total, the boys’ shared budget is a yuan.Besides, each of them has his own personal money, the i-th student has bi personal yuan.The shared budget can be spent on any student, but each boy’s personal money can be spent on buying only his gift.
Each boy can rent at most one gift, one cannot give his gift to sombody else.What maximum number of students will able to buy gifts?What minimum sum of personal money will they have to spend in total to let as many students buy gifts as possible?

输入

The first line of the input contains three integers n, m and a (1 ≤ n, m ≤ 1e5; 0 ≤ a ≤ 1e9). The second line contains the sequence of integers b1, b2, ..., bn (1 ≤ bi ≤ 1e4), where bi is the amount of the i-th student's personal money. The third line contains the sequence of integers p1, p2, ..., pm (1 ≤ pj ≤ 1e9), where pj is the price for renting the j-th gift.

输出

Print two integers r and s, where r is the maximum number of students that can buy a gift and s is the minimum total personal money needed to buy r gifts. If the students cannot buy any gifts, then r = s = 0.

样例输入

2 2 10

5 5

7 6

样例输出

2 3

二分 + 贪心

为获取 最大的购买个数,  二分查找最大区间,  然后补差值


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define FIN      freopen("input.txt","r",stdin)
#define FOUT     freopen("output.txt","w",stdout)
#define S1(n)    scanf("%d",&n)
#define SL1(n)   scanf("%I64d",&n)
#define S2(n,m)  scanf("%d%d",&n,&m)
#define SL2(n,m)  scanf("%I64d%I64d",&n,&m)
#define Pr(n)     printf("%d\n",n)
using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int MOD=1e9+7;
const int mod=1e9+7;
int dir[5][2]={0,1,0,-1,1,0,-1,0};
ll a[maxn],b[maxn];
int n,m, s;

bool judge(ll m)
{
    ll ssum=s;
    for(int i=1;i<=m;i++)
    {
        if(a[n-m+i]>b[i])
            continue;
        else
            ssum-=b[i]-a[n-m+i];
    }
    if(ssum<0)return false;
    return true;
}
int main()
{

    while(~scanf("%d %d %d",&n,&m,&s))
    {
        for(int i=1;i<=n;i++)
            S1(a[i]);
        for(int i=1;i<=m;i++)
            S1(b[i]);
        sort(a+1,a+n+1);
        sort(b+1,b+m+1);
        int ans=0;
        ll l=0,r=min(n,m);
        while(r-l>1)
        {
            ll mid=(l+r)>>1;
            if(judge(mid))
                l=mid;
            else
                r=mid;
        }
        if(judge(l)) ans=l;
        if(judge(r)) ans=r;
        int sum=0;
        for(int i=1;i<=ans;i++)
        {
            sum+=b[i];
           // cout<<b[i]<<" | "<<a[i]<<endl;
        }
        printf("%d %d\n",ans,max(sum-s,0));
    }
    return 0;
}


4198: Birthday present

时间限制: 1 Sec  内存限制: 128 MB
提交: 67  解决: 23
[提交][状态][讨论版]

题目描述

Bob’s father’s birthday is coming,.Because Bob’s father is a math teacher so that Bob wanted to give him an array of positive intergers a of length n as a gift.His father thinks that an array’s beauty is the greatest common divisor of all its elements. Bob wants to give him as beautiful an array as possible. But the shop has only one array a left. So Bob wants to decrease some numbers in the array(no more than K for each number).Bob can obtain array b from array a if the following conditions hold: bi > 0; 0 ≤ ai - bi ≤ k for all 1 ≤ i ≤ n.Help Bob find the maximum possible beauty of the array he will give to his father .

输入

The first line contains two integers n and k (1 ≤ n ≤ 3·1e5; 1 ≤ k ≤ 1e6). The second line contains n integers ai (1 ≤ ai ≤ 1e6) — array a.

输出

In the single line print a single number — the maximum possible beauty of the resulting array.

样例输入

6 1

3 6 10 12 13 16

样例输出

3


D - 爆搜;


判断最大公因数,   

  只需要判断  a[i] %x < =k  的个数 =n  则 x 即为答案,  x 从 最小的输入开始;

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define FIN      freopen("input.txt","r",stdin)
#define FOUT     freopen("output.txt","w",stdout)
#define S1(n)    scanf("%d",&n)
#define SL1(n)   scanf("%I64d",&n)
#define S2(n,m)  scanf("%d%d",&n,&m)
#define SL2(n,m)  scanf("%I64d%I64d",&n,&m)
#define Pr(n)     printf("%d\n",n)
using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int MOD=1e9+7;
const int mod=1e9+7;
int dir[5][2]={0,1,0,-1,1,0,-1,0};

int a[maxn];
int main()
{
    int n,k;
    while(~S2(n,k))
    {
        int ans=0;
        int x=INF;
        for(int i=1;i<=n;i++)
        {
            S1(a[i]);
            x=min(a[i],x);
        }
        if(x<=k)
            ans=x;
        for(int i=x;i>=k+1;i--)
        {
            int cont=0;
            for(int j=1;j<=n;j++){
                if(a[j]%i<=k)
                    cont++;
            }
            if(cont==n){
                ans=i;
                break;
            }
        }
        printf("%d\n",ans);

    }
    return 0;
}


问题 E: Make cubes

时间限制: 1 Sec  内存限制: 128 MB
提交: 76  解决: 20

题目描述

When he was a little boy, Jieba had always been interested in geometry.  One time, he got many pieces of colored square cards. For each color, he had as many pieces as he wanted. At that time, he decided to make some cubes using these cards. He wanted to know how many kinds of cubes could he make? (if one kind of cube can rotate to another kind, they will be seen the same)

输入

Every line of the input file defines a test case and contains one integer: the number of available colors n (0<n<1000)

输出

For each test case output on a single line the number of different kinds of cubes. Because the result may be too large, please mod the result with 1000000007.

样例输入

1
2

样例输出

1
10

这道题:  是  Burnside  染色 问题;


n 种 颜色  应为:    

 


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define FIN      freopen("input.txt","r",stdin)
#define FOUT     freopen("output.txt","w",stdout)
#define S1(n)    scanf("%d",&n)
#define SL1(n)   scanf("%I64d",&n)
#define S2(n,m)  scanf("%d%d",&n,&m)
#define SL2(n,m)  scanf("%I64d%I64d",&n,&m)
#define Pr(n)     printf("%d\n",n)

using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int MOD=1e9+7;
const int mod=1e9+7;
int dir[5][2]={0,1,0,-1,1,0,-1,0};

ll inv[maxn*2],fac[maxn];
ll gcd(ll a,ll b){ return b?gcd(b,a%b):a;}
ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll ans=exgcd(b,a%b,x,y);ll temp=x;x=y;y=temp-a/b*y;return ans;}
ll lcm(ll a,ll b){ return b/gcd(a,b)*a;}
ll qpow(ll x,ll n){ll res=1;for(;n;n>>=1){if(n&1)res=(res*x)%MOD;x=(x*x)%MOD;}return res;}
void INV(){inv[1] = 1;for(int i = 2; i < maxn; i++) inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){ x=1; y=0; d=a; }else{ ex_gcd(b,a%b,d,y,x); y-=x*(a/b);}}
void Fac(){fac[0]=1;for(int i=1;i<=maxn;i++)fac[i]=(fac[i-1]*i)%MOD;}
ll inv_exgcd(ll a,ll n){ll d,x,y;ex_gcd(a,n,d,x,y);return d==1?(x+n)%n:-1;}
ll inv1(ll b){return b==1?1:(MOD-MOD/b)*inv1(MOD%b)%MOD;}
ll inv2(ll b){return qpow(b,MOD-2);}
ll cal(ll m,ll n){if(m<n)return 0;return (fac[m]*inv[fac[n]]%MOD)%MOD*inv[fac[m-n]]%MOD;}
ll cals(ll m,ll n){if(m<n)return 0;return (fac[m]*inv1(fac[n])%MOD)%MOD*inv1(fac[m-n])%MOD;}


int main()
{
    int n;
    while(~S1(n))
    {

        printf("%lld\n",(qpow(n,6)+3*qpow(n,4)+12*qpow(n,3)+8*qpow(n,2))*inv1(24)%MOD);
    }
    return 0;
}


I -

 I: Coach's plan

时间限制: 2 Sec  内存限制: 128 MB
提交: 47  解决: 13
[提交][状态][讨论版]

题目描述

NEUACM team holds summer training every year. This year n  students participate in the training, and we provide m computers. Everyone has a suitability (0<=suitability<=1000) to every computer.
Now our coach needs to draw up a plan, which satisfies:
1. every student uses one computer, and a computer can be used by no more than one student;
2. maximize the minimum suitability, which means if the answer is w, then everyone's suitability to his computer shouldn't be less than w.

Hint: huge input, please use fast IO.

输入

The first line contains n and m (1<=n<=m<=500), indicating the number of students and computers.

Next n lines describes every student's suitability to every computer, number in ith line and jth row means student[i]'s suitability to computer[j].

输出

A single number w in one line, which is described before.

样例输入

1 2

1 1
0

2 3 

10 1 2

2 1 1

样例输出

10

2


找 最大的 里面最小的,  

重判之前 - -  找列最小水过的, 隔壁找行最小水过,   然后双双 over,   隔隔壁 找行 最小列最小 取最小 水过的 

竟然依然坚挺    - -   mmp


水过代码:

 找行列最小

 

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int n,m,a[505][505],b[505],c[505];

bool cmp(int x, int y){
	return x > y;
}

int main(){
	while(~scanf("%d%d",&n,&m)){
		for(int i = 0; i < n; i ++){
			for(int j = 0; j < m; j ++)
				scanf("%d",&a[i][j]);
		}
		for(int i = 0; i < n; i ++){
			int mxx = a[i][0];
			for(int j = 1; j < m; j ++)
				mxx = max(a[i][j],mxx);
			b[i] = mxx;
		}
		for(int j = 0; j < m; j ++){
			int mxx = a[0][j];
			for(int i = 1; i < n; i ++)
				mxx = max(a[i][j],mxx);
			c[j] = mxx;
		}
		sort(b,b+n,cmp);
		sort(c,c+m,cmp);
		
		printf("%d\n",min(c[n-1],b[n-1]));
	}
	return 0;
}


正解  二分图匹配 +二分 :

 

把网格 从一维 转成 二维:  

  • 这里写图片描述

这样的图 

 每行 选一个  每列 选一个, 并且 行列不能重复;

二分找到一个合适的,  然后将小于这个值得 划掉,  然后  取匹配剩下的是否有解:

 

用链式前向星 存储


123

posted @ 2017-08-30 19:51  Sizaif  阅读(207)  评论(0编辑  收藏  举报