8.17 纪中集训 Day17

  T1粉刷(paint)

Description

鸡腿想到了一个很高(sha)明(bi)的问题,墙可以看作一个N*M的矩阵,有一些格子是有污点的。现在鸡腿可以竖着刷一次,覆盖连续的最多C列,或者横着刷一次,覆盖连续的最多R行。现在鸡腿把墙上的情况告诉你,请你告诉鸡腿最少要刷多少次才能刷干净!

Input

第1行,输入俩正整数N,M。

第2到N+1行,每行一个长度为M的字符串,每个字符可能是’.’表示干净的,或者’X’表示这个格子有污点。

第N+2行,输入俩正整数表示R和C。

Output

输出一行一个整数,表示鸡腿最少要刷几次。

Sample Input

输入1:
1 9
XXXXXXXXX
2 3
输入2:

11 14
XXX..XXX..XXX.
.X..X....X...X
.X..X....X...X
.X..X....X...X
.X...XXX..XXX.
..............
...XX...XXX...
....X......X..
....X....XXX..
....X......X..
...XXX..XXX...
1 2

Sample Output

输出1:
1
输出2:
7

Data Constraint

对于50%的数据1≤N,M≤5;

对于100%的数据1≤N,M,R,C≤15。

正解

一个十分玄学的贪心。

Code

#include<cstring>
#include<cmath>
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,r,c;
char a[20][20];
int main()
{
    int sum=0;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>a[i][j];
            if(a[i][j]=='X')
            sum++;
        }
    }
    scanf("%d%d",&r,&c);
    if(sum==0)
    {
        cout<<"0"<<endl;
        return 0;
    }
    if(r>=n || c>=m)
    {
        cout<<"1"<<endl;
        return 0;
    }
    int ans=0;
    while(sum>0)
    {
        ans++;
        int nowmax=0,now=0,place,flag=0;
        for(int i=1;i<=n-r+1;i++)
        {
            now=0;
            for(int j=i;j<=i+r-1;j++)
                for(int k=1;k<=m;k++)
                    if(a[j][k]=='X')
                        now++;
            if(nowmax<now)
            {
                nowmax=now;
                place=i;
            }
        }    
        for(int i=1;i<=m-c+1;i++)
        {
            now=0;
            for(int j=1;j<=n;j++)
                for(int k=i;k<=i+c-1;k++)
                    if(a[j][k]=='X')
                        now++;
            if(nowmax<now)
            {
                nowmax=now;
                flag=1;
                place=i;
            }
        }
        sum-=nowmax;
        if(flag==0)
            for(int i=place;i<=place+r-1;i++)
                for(int j=1;j<=m;j++)
                    a[i][j]='.';
        else
            for(int i=1;i<=n;i++)
                for(int j=place;j<=place+c-1;j++)
                    a[i][j]='.';
    }    
    int ans1=n/r;
    int ans2=m/c;
    if(n%r!=0)
        ans1++;
    if(m%c!=0)
        ans2++;
    printf("%d",min(ans,min(ans1,ans2)));
    return 0;
}

T2运算符(calc) 

Description

鸡腿想到了一个很高(sha)明(bi)的运算符,那就是’!’,没错就是感叹号。他给了如下的定义:

1、n!k = n!(k-1) * (n-1)!k (n> 0 and k > 0)

2、n!k = 1 (n = 0)

3、n!k = n (k = 0)

现在鸡腿告诉你n和k你能告诉他n!k的不同约数个数有多少个吗?只要对1,000,000,009取模就可以了哦!

Input

一行,输入两个正整数n,k。

Output

一行,输出一个整数表示答案。

Sample Input

输入1:
3 1
输入2:
100 2

Sample Output

输出1:
4
输出2:
321266186

Data Constraint

对于30%的数据0 <n ≤ 10, 0 <k ≤ 10;

对于100%的数据0 <n ≤ 1000, 0 <k ≤ 100。

正解

自己对着代码理解吧,好困啊!!!

Code

#include<cstdio>
#include<algorithm>
#define LL long long
#define Mod 1000000009
using namespace std;

int n,k,sl,zhi;
LL ans;
int prime[202],low[1010];
int f[1010][110][202];

int main()
{
    scanf("%d%d",&n,&k);
    for(int i=2;i<=n;i++)
    {
        if(!low[i])
        {
            low[i]=i;
            prime[++sl]=i;
        }
        for(int j=1;j<=sl;j++)
        {
            if(prime[j]*i>n || prime[j]>low[i])
                break;
            low[i*prime[j]]=prime[j];
        }
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=sl;j++)
        {
            zhi=i;
            if(i%prime[j]==0)
                while(zhi%prime[j]==0)
                <%zhi/=prime[j];f[i][0][j]=(f[i][0][j]+1)%Mod;%>
        }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=k;j++)
        {
            for(int g=1;g<=sl;g++)
            {
                f[i][j][g]=(f[i-1][j][g]+f[i][j-1][g])%Mod;
            }
        }
    }
    ans=1;
    for(LL i=1;i<=sl;i++)
        ans=(ans*(1ll*f[n][k][i]+1))%Mod;
    printf("%lld",ans);
    return 0;
}

T3倾斜的线

Description

Input

Output

Sample Input

6 15698 17433
112412868 636515040
122123982 526131695
58758943 343718480
447544052 640491230
162809501 315494932
870543506 895723090 

Sample Output

193409386/235911335
 

Data Constraint

正解

将每个点到所给k值所对应直线的距离进行排序,可证所求答案一定排序后相邻两点所构成的k值中的最小值。

Code

#include<cmath>
#include<cstdio>
#include<algorithm>
#define NAME "slope"
using namespace std;

int n,p,q,s1,s2,g,a,b;
double k=999999.9;
int x[200020],y[200020];

pair<double,int> sz[200020];

void Open()<%freopen(NAME".in","r",stdin);freopen(NAME".out","w",stdout);%>

int Gcd(int a,int b)
<%return b==0 ? a : Gcd(b,a%b);%>

int main()
{
    Open();
    scanf("%d%d%d",&n,&p,&q);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x[i],&y[i]);
        sz[i]=make_pair(fabs((double)y[i]-x[i]/(double)q*(double)p),i);
    }
    sort(sz+1,sz+1+n);
    for(int i=1;i<n;i++)
    {
        s1=sz[i].second;s2=sz[i+1].second;
        if(fabs((double)(y[s1]-y[s2])/(double)(x[s1]-x[s2])-(double)p/q)<k || (fabs((double)(y[s1]-y[s2])/(double)(x[s1]-x[s2])-(double)p/q)==k && (double)a/b>(double)(y[s1]-y[s2])/(double)(x[s1]-x[s2])))
        {
            k=fabs((double)(y[s1]-y[s2])/(double)(x[s1]-x[s2])-(double)p/q);
            a=(y[s1]-y[s2]);b=(x[s1]-x[s2]);
        }
    }
    a=abs(a);b=abs(b);
    g=Gcd(a,b);
    printf("%d/%d",a/g,b/g);
    return 0;
}

总结

今天状态不好,看到代码就觉得有点烦,看来得调节一下态度了。

此间再无NOIp             祭

猜你喜欢

转载自www.cnblogs.com/Thm-V/p/11370422.html
今日推荐