您的位置:首页 > 其它

UVA 10623 - Thinking Backward(数论)

2014-07-02 12:59 267 查看


UVA 10623 - Thinking Backward

题目链接

题意:给定一个数量,求用圆,椭圆,三角形分割平面,分割出该数量,输出所有情况

思路:有公式2 + 2m(m-1) + n(n-1) + 4mn + 3p(p-1) + 6mp + 6np

由于m和p都是[0,100],所以可以枚举m和p,去求出n,然后判断合不合适

代码:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <vector>
#include <algorithm>
using namespace std;

//2 + 2m(m-1) + n(n-1) + 4mn + 3p(p-1) + 6mp + 6np

long long N, n;
struct Ans {
long long m, n, p;
Ans(long long m, long long n, long long p) {
this->m = m; this->n = n; this->p = p;
}
};

vector<Ans> ans;

bool cmp(Ans a, Ans b) {
if (a.m != b.m) return a.m < b.m;
if (a.n != b.n) return a.n < b.n;
return a.p < b.p;
}

void judge(long long m, long long p) {
long long a = 1;
long long b = (4 * m + 6 * p - 1);
long long c = 2 + 2 * m * (m - 1) + 3 * p * (p - 1) + 6 * m * p - N;
long long delta = b * b - 4 * a * c;
if (delta < 0) return;
long long tmp = (long long)(sqrt(delta));
if (tmp * tmp != delta) return;
long long n1 = -b + tmp, n2 = -b - tmp;
if (n1 % (2 * a) == 0) {
n1 /= (2 * a);
if (n1 >= 0 && n1 < 20000)
ans.push_back(Ans(m, n1, p));
}
if (n2 % (2 * a) == 0) {
n2 /= (2 * a);
if (n2 >= 0 && n2 < 20000)
ans.push_back(Ans(m, n2, p));
}
}

int main() {
int cas = 0;
while (~scanf("%lld", &N) && N != -1) {
printf("Case %d:\n", ++cas);
if (N == 1) {printf("0 0 0\n"); continue;}
ans.clear();
for (long long m = 0; m < 100; m++) {
for (long long p = 0; p < 100; p++)
judge(m, p);
}
if (!ans.size()) printf("Impossible.\n");
else {
sort(ans.begin(), ans.end(), cmp);
for (int i = 0; i < ans.size(); i++) {
if (ans[i].m == 0 && ans[i].n == 0 && ans[i].p == 0 && N != 1) continue;
printf("%lld %lld %lld\n", ans[i].m, ans[i].n, ans[i].p);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: