题目:
题目背景
SOURCE:NOIP2014-SXYZ T2
题目描述
小美去看电影,发现这个电影票很神奇,有一个编号 (x,y) 表示为第 x 排第 y 位。
小美是个聪明的女孩子,她有自己的一套对于幸运的编号的定义:如果(a,b) 如果是幸运的,那么 a*b=rev(a)*rev(b),a>0,b>0。rev(x) 的定义是把 x 的十进制的数字翻转,比如:rev(20010)=1002,rev(1010)=101。
现在她想要至少 w 张幸运的电影票,问座位至少有几个。
座位个数为:max(a)*max(b),且要保证 max(a)≤maxa 和 max(b)≤maxb 。
输入格式
第一行有 3 个数 maxa,maxb,w。
输出格式
输出最少的座位个数,如果无解输出“-1”。
样例数据 1
样例数据 2
样例数据 3
样例数据 4
备注
【数据规模与约定】
对于 30% 的数据:1≤maxa,maxb≤1000;
对于 100% 的数据:1≤maxa,maxb≤105;1≤w≤107。
题解:
这个真心不好讲····大概就是删列加行的过程····看代码吧
代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<cstring> #include<string> #include<algorithm> #include<map> using namespace std; map<double,int>f;//记录已知行中x/rev(x)的个数 map<double,int>g;//记录已知列中x/rev(x)的个数 double b[100005],c[100005];//分别记录x/rev(x),rev(x)/x; int n,m,k; long long ans,i,j,h; inline int fan(int x) { int k1=x,f=0; for(;k1;k1/=10) f=f*10+k1%10; return f; } int main() { //freopen("a.in","r",stdin); scanf("%d%d%d",&n,&m,&k); for(i=1;i<=max(n,m);i++) { int l=fan(i); b[i]=(double)i/l; c[i]=(double)l/i; } for(i=1;i<=n;i++) f[b[i]]++; for(j=0;j<m&&h<k;) { j++; g[b[j]]++; h+=f[c[j]]; } ans=i*j; if(ans<k) cout<<"-1"<<endl; for(;i>0;i--) { f[b[i]]--; h-=g[c[i]]; for(;j<m&&h<k;) { j++; h+=f[c[j]]; g[b[j]]++; } if(h<k) break; ans=min(ans,(i-1)*j); } cout<<ans<<endl; return 0; }