首页 > 代码库 > UVa 11490 Just Another Problem

UVa 11490 Just Another Problem

方法:数学 整除

根据推导发现新的方阵长为2*x+3*d, 宽为 x+2*d, 面积满足方程 (2*x+3*d)*(x+2*d) = S + 2*x*x。 (d为thickness)

 

 

(比较合理的方法)

继而得到 x = (S-6*d*d)/(7*d) 枚举d即可。

code:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <bitset>
#include <cstdlib>
#include <cmath>
#include <set>
#include <list>
#include <deque>
#include <map>
#include <queue>
#include <fstream>
#include <cassert>
#include <unordered_map>
#include <cmath>
#include <sstream>
#include <time.h>
#include <complex>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define FOR(a,b,c) for (int (a)=(b);(a)<(c);++(a))
#define FORN(a,b,c) for (int (a)=(b);(a)<=(c);++(a))
#define DFOR(a,b,c) for (int (a)=(b);(a)>=(c);--(a))
#define FORSQ(a,b,c) for (int (a)=(b);(a)*(a)<=(c);++(a))
#define FORC(a,b,c) for (char (a)=(b);(a)<=(c);++(a))
#define FOREACH(a,b) for (auto &(a) : (b))
#define rep(i,n) FOR(i,0,n)
#define repn(i,n) FORN(i,1,n)
#define drep(i,n) DFOR(i,n-1,0)
#define drepn(i,n) DFOR(i,n,1)
#define MAX(a,b) a = Max(a,b)
#define MIN(a,b) a = Min(a,b)
#define SQR(x) ((LL)(x) * (x))
#define Reset(a,b) memset(a,b,sizeof(a))
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define all(v) v.begin(),v.end()
#define ALLA(arr,sz) arr,arr+sz
#define SIZE(v) (int)v.size()
#define SORT(v) sort(all(v))
#define REVERSE(v) reverse(ALL(v))
#define SORTA(arr,sz) sort(ALLA(arr,sz))
#define REVERSEA(arr,sz) reverse(ALLA(arr,sz))
#define PERMUTE next_permutation
#define TC(t) while(t--)
#define forever for(;;)
#define PINF 1000000000000
#define newline ‘\n‘

#define test if(1)if(0)cerr
using namespace std;
  using namespace std;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
typedef pair<double,double> dd;
typedef pair<char,char> cc;
typedef vector<ii> vii;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> l4;
const double pi = acos(-1.0);

const int mod = 100000007;
const string str = "Possible Missing Soldiers = ", no = "No Solution Possible";

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll s;
    while (cin >> s && s)
    {
        vector<ll> ans;
        for (ll d = 1; d*d*6 < s; ++d)
        {
            ll x = s - 6*d*d;
            if (x % (7*d)) continue;
            x /= 7*d;
            ans.pb((x%mod)*(x%mod)*2%mod);
        }
        if (ans.size() == 0)
            cout << no << newline;
        else
        {
            rep(i, ans.size())
            cout << str << ans[i] << newline;
        }
        cout << newline;
    }
}

  

 

(我的傻方法)

利用求根公式,得到d的解为((49*x*x+24*S)^0.5 - 7*x)/12。

可以观察到,当x足够大时,49*x*x+24*S 无法构成一个平方数((7*x+1)^2 - (7*x)^2 = 14*x, 相邻的两个平方数的距离是不断增加的,当14*x > 24*S且S大于0时,49*x*x+24*S 不可能使平方数)。

所以 设 (7*x + a) = (49*x*x+24*S)^0.5, 枚举a。 注意 (7x+a)^2 - (7*x)^2 = a * (14x+a) = 24*S。 所以 a*a < 24*S, a < (24*S)^0.5 < 5e6, 可以接受。然后可以发现,d的解为((49*x*x+24*S)^0.5 - 7*x)/12 = (7*x+a - 7*x)/12 = a/12, 枚举 a的时候可以只枚举大于零 12的倍数,枚举的数量不超过 5e6/12, 对于1e3个testcase,时效足够了。

 

code: 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <bitset>
#include <cstdlib>
#include <cmath>
#include <set>
#include <list>
#include <deque>
#include <map>
#include <queue>
#include <fstream>
#include <cassert>
#include <unordered_map>
#include <cmath>
#include <sstream>
#include <time.h>
#include <complex>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define FOR(a,b,c) for (int (a)=(b);(a)<(c);++(a))
#define FORN(a,b,c) for (int (a)=(b);(a)<=(c);++(a))
#define DFOR(a,b,c) for (int (a)=(b);(a)>=(c);--(a))
#define FORSQ(a,b,c) for (int (a)=(b);(a)*(a)<=(c);++(a))
#define FORC(a,b,c) for (char (a)=(b);(a)<=(c);++(a))
#define FOREACH(a,b) for (auto &(a) : (b))
#define rep(i,n) FOR(i,0,n)
#define repn(i,n) FORN(i,1,n)
#define drep(i,n) DFOR(i,n-1,0)
#define drepn(i,n) DFOR(i,n,1)
#define MAX(a,b) a = Max(a,b)
#define MIN(a,b) a = Min(a,b)
#define SQR(x) ((LL)(x) * (x))
#define Reset(a,b) memset(a,b,sizeof(a))
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define all(v) v.begin(),v.end()
#define ALLA(arr,sz) arr,arr+sz
#define SIZE(v) (int)v.size()
#define SORT(v) sort(all(v))
#define REVERSE(v) reverse(ALL(v))
#define SORTA(arr,sz) sort(ALLA(arr,sz))
#define REVERSEA(arr,sz) reverse(ALLA(arr,sz))
#define PERMUTE next_permutation
#define TC(t) while(t--)
#define forever for(;;)
#define PINF 1000000000000
#define newline ‘\n‘

#define test if(1)if(0)cerr
using namespace std;
  using namespace std;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
typedef pair<double,double> dd;
typedef pair<char,char> cc;
typedef vector<ii> vii;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> l4;
const double pi = acos(-1.0);

const int mod = 100000007;
const string str = "Possible Missing Soldiers = ", no = "No Solution Possible";

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll s;
    while (cin >> s && s)
    {
        vector<ll> ans;
        ll bound = sqrt(24*s+0.5);
        for (ll a = 12; a <= bound; a += 12)
        {
            if (24*s%a != 0) continue;
            ll x = 24*s/a-a;
            if (x % 14 != 0) continue;
            x /= 14;
            if (x == 0) continue;
            ans.pb((x%mod)*(x%mod)*2%mod);
        }
        if (ans.size() == 0)
            cout << no << newline;
        else
        {
            rep(i, ans.size())
            cout << str << ans[i] << newline;
        }
        cout << newline;
    }
}

  

UVa 11490 Just Another Problem