C. 三角形的传说 2014新生暑假个人排位赛07
时间限制 1000 ms
内存限制 65536 KB
题目描述
有一个传说,对给定正整数 m 和 q,总有一个边长为 a,b,c 的三角形,是满足 a % m + b % m = c % m = q 的条件的三角形中周长最小的。
Mays 对此深信不疑,她打算和你一起探讨这个问题。她出了一些数据,请你帮忙求最小周长,如果找不到这样一个三角形,也请你告诉她这个惨痛的事实。
输入格式
给一个组数 T。接下来 T 组,每组两个数字 m 和 q ,(1 <= m <= 10^5 , 0 <= q < m)。
输出格式
输出当前组数和最小周长,格式见样例。若不存在满足的三角形,请把最小周长的数字替换成"Poor Mays!".
输入样例
2
3 2
3 2
输出样例
Case 1: 7
Case 2: 7
思路:你知道的c%m的值,然后假设a%m小于b%m,枚举a%m,如果不能构成三角形就把最小的边加上M然后比较剩余两条边是不是打过他,若三个都加了还不能满足要求,则之后的必不能满足要求。故仅需O(1)的时间判断。就可以过了。
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
//#define LOCAL
using namespace std;
int ans;
int m,q,a,b,c;
void solve(int a,int b,int c)
{
//printf("a=%d b=%d c=%d\n",a,b,c);
if(a+b<=c)
{
if(b+c<=a+m)
{
if(c+a+m<=b+m)
{
if(a+b+2*m<=c+m)return;
else
{
if(a+b+2*m+c+m<ans)ans=a+b+2*m+c+m;
return;
}
}
else
{
if(c+a+m+b+m<ans)ans=c+a+m+b+m;
return;
}
}
else
{
if(b+c+a+m<ans)ans=b+c+a+m;
return;
}
}
else
{
if(a+b+c<ans)ans=a+b+c;
return;
}
}
int main()
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
#endif // LOCAL
int T,Case;
scanf("%d",&T);
for(Case=1;Case<=T;Case++)
{
scanf("%d%d",&m,&q);
ans=1000000000;
for(a=0;a<=(q-1)/2;a++)
{
b=q-a;c=q;
solve(a,b,c);
}
if(ans!=1000000000)printf("Case %d: %d\n",Case,ans);
else printf("Case %d: Poor Mays!\n",Case);
}
return 0;
}