刷题总结——电影(ssoi)

题目:

题目背景

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 2 1

输出

1

样例数据 2

输入  [复制]

 

 

132 10 35

输出

35

样例数据 3

输入  [复制]

 

 

5 18 1000

输出

-1

样例数据 4

输入  [复制]

 

 

48 132 235

输出

2442

备注

【数据规模与约定】
对于 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;
}

 

posted @ 2017-07-08 15:36  AseanA  阅读(229)  评论(0编辑  收藏  举报