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。
第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。
对于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取模就可以了哦!
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。
对于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; }
总结
今天状态不好,看到代码就觉得有点烦,看来得调节一下态度了。