hdu6512Triangle
theme:判断n个数中可否存在构成三角形的三个数。
solution:对于n个数找构成三角形的三个数的题,按数据范围有不同解法。想法是将这n个数从小到大排序,(下标从0开始),之后从i=1开始,将i,i+1作为三角形较大的两边,判断它们的差(正值)d是否<a[i-1]即可,因为一旦<则满足条件,一旦>,则d更>i-1之前的数了(要使c-b<a,则找到c-b最小值和a最大值,由于c-b最小处可能取多个,所以我们就遍历每一个c-b即可,这样c-b最小即为每个相邻数之差)。这样做时间复杂度就是排序的时间o(nlog(n)),但该题n较大,又存在多组测试数据,o(nlog(n))关闭流同步才1994ms险过,所以考虑进一步优化:
由上述思路转化为两边之和大于第三边的话,相邻两数a[i],a[i+1]之和要是<a[i+2]也一定小于它后面的数,所以遍历时,极端情况就是1,2,3,5,8,13、、、刚好=情况,由斐波那契数列算出n到50左一点就超int了,所以可看n>=50时一定存在三个数(排序后)组成三角形。
#include <cstdio>
#include <list>
#include<iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
int a[5000010];
ll fib[200];
int main()
{
ios::sync_with_stdio(false);
// fib[0]=1,fib[1]=1;
// for(int i=2;i<=100;++i)
// fib[i]=fib[i-1]+fib[i-2];
// cout<<fib[50];
int n;
while(cin>>n)
{
for(int i=0;i<n;++i)
cin>>a[i];
if(n<2)
{
cout<<"NO\n";
continue;
}
if(n>=50)
{
cout<<"YES\n";
continue;
}
sort(a,a+n);
int flag=0;
for(int i=1;i<n-1;++i)
{
int b=a[i+1]-a[i];
if(b<a[i-1])
{
flag=1;
break;
}
}
if(flag)
cout<<"YES\n";
else
cout<<"NO\n";
}
return 0;
}
hdu6518Clumsy Keke
theme:由矩阵形式给定三视图,一小格代表体积为1.问满足该三视图的图形的最大体积为多少?
solution:题目输入并不是直接按主视图、左视图、俯视图角度给的,所以先确定一下x,y,z轴方向。想象一个由x*y*z的格子堆成的正方体。对于每一视图,如主视图,该格上有图形,则表示它及它后面的格子都可能放小正方体。这样由三个视图的&关系可以确定哪些格子上是可以放小正方体的。
#include <cstdio>
#include <list>
#include <cstring>
#include<iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
int Front[110][110];
int Left[110][110];
int Top[110][110];
int ans[110][110][110];
int main()
{
int mx,my,mz;
while(~scanf("%d%d%d",&mx,&my,&mz))
{
for(int i=0;i<mx;++i)
for(int j=0;j<my;++j)
scanf("%d",&Front[i][j]);
for(int i=0;i<my;++i)
for(int j=0;j<mz;++j)
scanf("%d",&Left[i][j]);
for(int i=0;i<mz;++i)
for(int j=0;j<mx;++j)
scanf("%d",&Top[i][j]);
for(int i=0;i<mx;++i)
for(int j=0;j<my;++j)
for(int z=0;z<mz;++z)
ans[i][j][z]=Front[i][j];
for(int j=0;j<my;++j)
for(int z=0;z<mz;++z)
for(int i=0;i<mx;++i)
ans[i][j][z]&=Left[j][z];
for(int z=0;z<mz;++z)
for(int i=0;i<mx;++i)
for(int j=0;j<my;++j)
ans[i][j][z]&=Top[z][i];
int res=0;
for(int i=0;i<mx;++i)
for(int j=0;j<my;++j)
for(int z=0;z<mz;++z)
res+=ans[i][j][z];
printf("%d\n",res);
}
}