zoukankan      html  css  js  c++  java
  • codeforces 451C. Predict Outcome of the Game 解题报告

    题目链接:http://codeforces.com/problemset/problem/451/C

    题目意思:有3支球队(假设编号为1、2、3),总共要打 n 场比赛,已知已经错过这n场比赛中的 k 场,但从 k 场比赛中可以获取一些信息:设w1表示 k 场比赛中编号为1的球队赢了w1场比赛(w2、w3 类似),绝对值 |w1-w2| = d1,  |w2-w3| = d2,问能否通过设置n-k 的 赛果来使得n场比赛都打完后,编号为1的球队的胜利次数 == 编号为2的球队的胜利次数  == 编号为3的球队的胜利次数。注意:每场比赛的赛果只有胜和输之分,没有平局。

          初时看到这道题目,完全没有思路,当看了Tutorial 之后(不过没仔细看他的solution),就大概知道怎么做了,贡献了两个wa......

          首先对于n,如果不能被 3 整除,那就肯定怎么分配剩下的 n-k 场赛果都于事无补的了,因为最终 编号为1的球队的胜利次数 == 编号为2的球队的胜利次数  == 编号为3的球队的胜利次数 == n / 3 嘛

      其次,要得出一条隐含的方程(关键所在): w1 + w2 + w3 = k!  (1)

          然后结合 |w1-w2| = d1 (2),  |w2-w3| = d2 (3) 来得出w1、 w2、 w3的值。(绝对值可以通过w1,w2,w3的大小关系来去掉,有四种情况)

        (1)w1 >= w2,w2 >= w3                                      (2)w1 >= w2,w2 < w3

    ——>  w1 = (2d1 + d2 + k)  / 3              ——>  w1 = (2d1 - d2 + k)  / 3

              w2 = (-d1 + d2 + k)  / 3                  w2  = (-d1 - d2 + k)  / 3

              w3 = (-d1 - 2d2 + k) / 3                  w3  = (-d1 + 2d2 + k)  / 3

        (3)w1 < w2,w2 >= w3                                          (4)w1 < w2,w2 < w3

    ——>  w1 = (-2d1 + d2 + k)  / 3                ——>  w1 = (-2d1 - d2 + k)  / 3

        w2 = ( d1   + d2 + k )  / 3                  w2 = ( d1   - d2 + k )  / 3

        w3 = ( d1   - 2d2 + k)  / 3                  w3 = ( d1  + 2d2 + k)  / 3

          可以知道,x1与x2的大小关系只会影响 d1 的符号,x2与x3的大小关系只会影响 d2 的符号。

          那么可以枚举d1与d2的符号(当然不可能是0啦),算出相应的x1, x2, x3 的大小,看看每个xi (1 <= i <= 3 ) 是否满足 0 <= xi <= n/3 (前提是n%3 == 0!下界0一定要加上,因为算出来有可能是负数啊),还有一点就是,由于涉及除法,4 / 3 == 1 这些情况要考虑到,一个可以避免的方法是,计算的时候,分子要判断是否能被3整除,不能就continue 咯。

           总的来说,这题是纯数学题!

           

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 using namespace std;
     6 
     7 __int64 n, k, d1, d2;
     8 
     9 int main()
    10 {
    11     int t;
    12     while (scanf("%d", &t) != EOF)
    13     {
    14         while (t--)
    15         {
    16             scanf("%I64d%I64d%I64d%I64d", &n, &k, &d1, &d2);
    17             if (n % 3)
    18                 printf("no
    ");
    19             else
    20             {
    21                 int flag = 0;
    22                 for (int s1 = -1; s1 <= 1 && !flag; s1++)  // 控制d1的正负号
    23                 {
    24                     for (int s2 = -1; s2 <= 1 && !flag; s2++)  // 控制d2的正负号
    25                     {
    26                         if (s1 == 0 || s2 == 0)
    27                             continue;
    28                         __int64 w1, w2, w3;
    29                         __int64 f1, f2, f3;  // w1, w2, w3的分子
    30                         f1 = (2*(s1)*d1 + (s2)*d2 + k);
    31                         if (f1 % 3)
    32                             continue;
    33                         w1 = f1 / 3;
    34                         f2 = ((-1)*(s1)*d1 + (s2)*d2 + k);
    35                         if (f2 % 3)
    36                             continue;
    37                         w2 = f2 / 3;
    38                         f3 = ((-1)*(s1)*d1 + 2*(-1)*(s2)*d2 + k);
    39                         if (f3 % 3)
    40                             continue;
    41                         w3 = f3 / 3;
    42     
    43                         if (w1 + w2 + w3 == k && w1 >= 0 && w1 <= n/3 && w2 >= 0 && w2 <= n/3 && w3 >= 0 && w3 <= n/3)
    44                         {
    45                             flag = 1;
    46                             break;
    47                         }
    48                     }
    49                 }
    50                 printf("%s
    ", flag ? "yes" : "no");
    51             }
    52         }
    53     }
    54     return 0;
    55 }
  • 相关阅读:
    松软科技web课堂:SQLServer之ROUND() 函数
    松软科技web课堂:SQLServer之LEN() 函数
    接口工具比较
    记录EXCEL格式和TXT文本格式之间的互转
    Fiddler安装证书
    Nginx概述及安装配置
    YSLOW(一款实用的网站性能检测工具)
    通用测试用例大全
    Macaca环境配置及样例执行
    ADB命令
  • 原文地址:https://www.cnblogs.com/windysai/p/3870749.html
Copyright © 2011-2022 走看看