[杂题]CSUOJ1274Balls and Boxes

题目链接

题意:中文题 题意不多赘述

值得注意的是n<m 不必考虑n==m的情况 (m是盒子个数, n是每次选取的盒子个数, 不要弄反了!)

 

这题一看就是同余方程

 

每次选取n个盒子放球 也就是说每次都增加n个球

最后m个盒子中球的个数相等, 也就是最终状态球的总数为m的倍数

于是 很容易能得到同余方程:sum+x*n=y*m   (sum为出示状态共有sum个球)

其中x为 需要选x次盒子放球  

  y为 最终每个盒子有y个球

 

接下来只要解同余方程

若无解, 则无论怎样操作都不能达到这个目的

若有解 还需满足几个条件:

  (首先需要记录一下:初始状态最多的盒子里有maxn个球, 最少的有minn个球)

  y>=maxn   也就是最后每个盒子里的球的个数 肯定要大于或者等于初始状态的 盒子中有的球的最大个数

  x>=y-minn  也就是 选盒子放球的次数 肯定要大于或者等于 最终状态每个盒子内球的个数 与 初始状态盒子中有的球的最小个数 之差

 

[杂题]CSUOJ1274Balls and Boxes
 1 #include <cstdio>

 2 #include <cstdlib>

 3 #include <cstring>

 4 #include <climits>

 5 #include <cctype>

 6 #include <cmath>

 7 #include <string>

 8 #include <sstream>

 9 #include <iostream>

10 #include <algorithm>

11 #include <iomanip>

12 using namespace std;

13 #include <queue>

14 #include <stack>

15 #include <vector>

16 #include <deque>

17 #include <set>

18 #include <map>

19 typedef long long LL;

20 typedef long double LD;

21 const double pi=acos(-1.0);

22 const double eps=1e-9;

23 #define INF 0x3f3f3f

24 #define lson l, m, rt<<1

25 #define rson m+1, r, rt<<1|1

26 typedef pair<int, int> PI;

27 typedef pair<int, PI > PP;

28 #ifdef _WIN32

29 #define LLD "%I64d"

30 #else

31 #define LLD "%lld"

32 #endif

33 //#pragma comment(linker, "/STACK:1024000000,1024000000")

34 //LL quick(LL a, LL b){LL ans=1;while(b){if(b & 1)ans*=a;a=a*a;b>>=1;}return ans;}

35 //inline int read(){char ch=' ';int ans=0;while(ch<'0' || ch>'9')ch=getchar();while(ch<='9' && ch>='0'){ans=ans*10+ch-'0';ch=getchar();}return ans;}

36 inline void print(LL x){printf(LLD, x);puts("");}

37 //inline void read(LL &ret){char c;int sgn;LL bit=0.1;if(c=getchar(),c==EOF) return ;while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();sgn=(c=='-')?-1:1;ret=(c=='-')?0:(c-'0');while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');if(c==' '||c=='\n'){ ret*=sgn; return ; }while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;ret*=sgn;}

38 

39 void ex_gcd(LL a, LL b, LL &d, LL &x, LL &y)

40 {

41     if(b)

42     {

43         ex_gcd(b, a%b, d, x, y);

44         LL tmp=x;

45         x=y;

46         y=tmp-(a/b)*y;

47     }

48     else

49     {

50         x=1, y=0, d=a;

51         return ;

52     }

53 }

54 int main()

55 {

56     int t;

57     scanf("%d", &t);

58     while(t--)

59     {

60         int n, m;

61         scanf("%d%d", &n, &m);

62         int sum=0, maxn=0, minn=INT_MAX;

63         for(int i=0;i<n;i++)

64         {

65             int a;

66             scanf("%d", &a);

67             sum+=a;

68             maxn=max(maxn, a);

69             minn=min(minn, a);

70         }

71         LL d, x, y;

72         ex_gcd(n, m, d, x, y);

73         if(sum%d)

74             printf("-1\n");

75         else

76         {

77             x*=sum/d;

78             y*=sum/d;

79             LL ans1=(maxn-x)*d/m;

80             LL ans2=(x+y-minn)*d/(n-m);

81             if((x+m/d*ans1)<maxn) ans1++;

82             if((n/d*ans2-y)<((x+m/d*ans2)-minn)) ans2++;

83             print(n/d*max(ans1, ans2)-y);

84         }

85     }

86     return 0;

87 }
CSUOJ 1274

 

 

 

最后。。。以上是纯YY的结果。。。具体的证明还是直接看官方题解好了,反正我也证不出来(题解:http://acm.csu.edu.cn/csuacm/2013/04/)

 

你可能感兴趣的:(ls)