標籤:style http color get width os
題目連結:uva 10623 - Thinking Backward
題目大意:就是給出N,表示要將平面分解成N份,問有哪些可選則的方案,m表示橢圓、n表示圓形、p表示三角形的個數,m、n、p分別給定範圍。
解題思路:本來這題一點思路都沒有,但是在論壇上看到一個公式N=2+2m(m?1)+n(n?1)+4mn+3p(p?1)+6mp+6np
這樣只要枚舉m和p,求解n,判斷n是否滿足即可,注意n一定是整數。
#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;typedef long long ll;const int N = 100005;struct state { ll n, m, p; void set (ll m, ll n, ll p) { this->m = m; this->n = n; this->p = p; }}s[N];bool cmp (const state& a,const state& 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;}int main () { int cas = 1; ll n; while (scanf("%lld", &n) == 1 && n != -1) { printf("Case %d:\n", cas++); if (n == 1) { printf("0 0 0\n"); continue; } int c = 0; for (ll m = 0; m < 100; m++) { for (ll p = 0; p < 100; p++) { ll sum = 2 + 2 * m * (m-1) + 3 * p * (p-1) + 6 * m * p; sum = n - sum; ll a = 4 * m + 6 * p - 1; /* if (m == 0 && p == 0) printf("%lld %lld! \n", sum, a); */ double tmp = sum + a * a / 4.0; if (tmp < 0) continue; tmp = sqrt(tmp); double x = (tmp - ((double)a / 2.0)); if (x < 0 || x >= 20000) continue; ll n = x; /* */ if (n * n + a * n == sum) s[c++].set(m, n, p); } } sort (s, s + c, cmp); if (c) { for (int i = 0; i < c; i++) printf("%lld %lld %lld\n", s[i].m, s[i].n, s[i].p); } else printf("Impossible.\n"); } return 0;}