C. Unfair Poll 数学题,

http://codeforces.com/contest/758/problem/C

需要一个能够找到任意一个位置的步数的方法,就能解决三个问题。

预处理出one(row, col)表示第一次经过这个点,需要的步数。

sec(row, col),thr(row, col)分别是第二、三步。

那么,循环节就会产生,记录步数为X, Y, Z,那么,第一二步的差距,和第二三步的差距,分别代表了从下走上去和从上走下来。

那么第4次,就会和第一二步的差距相等

就比如是5、17、23,那么下一步就是35.

但是预处理这个one\sec\thr也特别多细节。

 

然后就可以用循环节了,5 + 每18个增加两次,还要特判下剩余的再够一次。

 

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;


#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
int n, m, x, y;
LL tk;
int one(int row, int col) {
    return (row - 1) * m + col;
}
int sec(int row, int col) {
    if (row == n) {
        return n * m + (n - 1) * m  + col + (max(0, n - 2) * m);
    } else if (row == 1) {
        return n * m + max(0, (n - 2)) * m + col;
    }
    return one(row, col) + m - col + (n - row) * m + max((n - 1 - row), 0) * m + col;
}
int thr(int row, int col) {
    if (row == 1) {
        if (n == 1) {
            return m * 2 + col;
        }
        return n * m + (n - 1) * m * 2 + m * (max(0, n - 2)) + col;
    } else if (row == n) {
        return n * m + (n - 1) * m * 3 + max(0, (n - 2)) * m + col;
    }
    return sec(row, col) + (row - 1) * m + (row - 2) * m + m;
}
LL tofind(int row, int col) {
    LL k = tk;
    if (k <= one(row, col)) return k >= one(row, col);
    k -= one(row, col);
    int cir = thr(row, col) - one(row, col);
    LL ans = 1LL + (k / cir) * 2;
    ans += k % cir >= sec(row, col) - one(row, col);
    return ans;
}
void work() {
    cin >> n >> m >> tk >> x >> y;
//    cout << one(x, y) << " " << sec(x, y) << " " << thr(x, y) << endl;
    LL ansmx = -1, ansmi = 1e18L;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j  <= m; ++j) {
            ansmx = max(ansmx, tofind(i, j));
            ansmi = min(ansmi, tofind(i, j));
        }
    }
    cout << ansmx << " " << ansmi << " " << tofind(x, y) << endl;
}

int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    work();
    return 0;
}
View Code

 

posted on 2017-01-20 02:41  stupid_one  阅读(180)  评论(0编辑  收藏  举报

导航