Diagonal Walking v.2 CodeForces - 1036B (思维,贪心)

Diagonal Walking v.2

CodeForces - 1036B

Mikhail walks on a Cartesian plane. He starts at the point (0,0)(0,0), and in one move he can go to any of eight adjacent points. For example, if Mikhail is currently at the point (0,0)(0,0), he can go to any of the following points in one move:

  • (1,0)(1,0);
  • (1,1)(1,1);
  • (0,1)(0,1);
  • (?1,1)(?1,1);
  • (?1,0)(?1,0);
  • (?1,?1)(?1,?1);
  • (0,?1)(0,?1);
  • (1,?1)(1,?1).

If Mikhail goes from the point (x1,y1)(x1,y1) to the point (x2,y2)(x2,y2) in one move, and x1≠x2x1≠x2 and y1≠y2y1≠y2, then such a move is called a diagonal move.

Mikhail has qq queries. For the ii-th query Mikhail‘s target is to go to the point (ni,mi)(ni,mi) from the point (0,0)(0,0) in exactly kiki moves. Among all possible movements he want to choose one with the maximum number of diagonal moves. Your task is to find the maximum number of diagonal moves or find that it is impossible to go from the point (0,0)(0,0) to the point (ni,mi)(ni,mi) in kiki moves.

Note that Mikhail can visit any point any number of times (even the destination point!).

Input

The first line of the input contains one integer qq (1≤q≤1041≤q≤104) — the number of queries.

Then qq lines follow. The ii-th of these qq lines contains three integers nini, mimi and kiki (1≤ni,mi,ki≤10181≤ni,mi,ki≤1018) — xx-coordinate of the destination point of the query, yy-coordinate of the destination point of the query and the number of moves in the query, correspondingly.

Output

Print qq integers. The ii-th integer should be equal to -1 if Mikhail cannot go from the point (0,0)(0,0) to the point (ni,mi)(ni,mi) in exactly kiki moves described above. Otherwise the ii-th integer should be equal to the the maximum number of diagonal moves among all possible movements.

Example

Input

32 2 34 3 710 1 9

Output

16-1

Note

One of the possible answers to the first test case: (0,0)→(1,0)→(1,1)→(2,2)(0,0)→(1,0)→(1,1)→(2,2).

One of the possible answers to the second test case: (0,0)→(0,1)→(1,2)→(0,3)→(1,4)→(2,3)→(3,2)→(4,3)(0,0)→(0,1)→(1,2)→(0,3)→(1,4)→(2,3)→(3,2)→(4,3).

In the third test case Mikhail cannot reach the point (10,1)(10,1) in 9 moves.

题意:

为了防止比赛被ak!为了守护世界的和平!我们!贯彻爱与真实的险恶!恩爱又迷人的出题组!!决定!!!把zzq抓起来,放到一个荒无人烟岛上。zzq所在的位置是(0,0),而离开荒岛的传送阵在(n,m),zzq的体力值只够他走k步,zzq每次可以走8个方向。
(1,0)
(1,1)
(0,1)
(?1,1)
(?1,0)
(?1,?1)
(0,?1)
(1,?1)
但是温柔善良的大魔王SYH怎么会让zzq轻易的逃离荒岛,所以她希望zzq尽量多地往斜方向走,传送阵仅在第k秒开启,口令就是zzq最多可以往斜方向走的步数。
可怜的zzq被土拨鼠吸走了所有的脑细胞,于是他打电话给你想让你帮他解出口令。

思路:

如果 x > y 先swap(x,y),交换xy并不影响答案。

然后 先从( 0 ,0 )走到(x,x)

然后再竖直向上走,

我们令z=k-x,

如果剩下的路程 y=(y-x)

那么接下来

如果y和z都是奇数,用z中的一个1,走y中的一个单位。

两者都变成偶数,而偶数可以通过这样的走法使剩下的全部z都走歇着的。

否则如果y和z中只有一个是奇数,用z中的偶数部分去全走斜的,答案再必须减去1.

细节见代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int* p);
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int q;
ll x, y, k;
int main()
{
    //freopen("D:\\common_text\\code_stream\\in.txt","r",stdin);
    //freopen("D:\\common_text\\code_stream\\out.txt","w",stdout);
    scanf("%d", &q);
    while (q--)
    {
        scanf("%lld %lld %lld", &x, &y, &k);
        if (x > y)
        {
            swap(x, y);
        }
        ll z = k - x;
        y -= x;
        if (z < y)
        {
            printf("-1\n");
        } else
        {
            if (z & 1)
                x += z - 1;
            else
                x += z;
            if (y & 1)
            {
                y = 1;
            } else
            {
                y = 0;
            }
            if (z & 1)
            {
                z = 1;
            } else
            {
                z = 0;
            }
            if (z & y)
            {

            } else if (z + y)
            {
                x--;
            }
            printf("%lld\n", x );
        }
    }

    return 0;
}

inline void getInt(int* p) {
    char ch;
    do {
        ch = getchar();
    } while (ch == ' ' || ch == '\n');
    if (ch == '-') {
        *p = -(getchar() - '0');
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 - ch + '0';
        }
    }
    else {
        *p = ch - '0';
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 + ch - '0';
        }
    }
}

原文地址:https://www.cnblogs.com/qieqiemin/p/11515936.html

时间: 2024-08-29 10:04:15

Diagonal Walking v.2 CodeForces - 1036B (思维,贪心)的相关文章

Codeforces 1036B Diagonal Walking v.2 【贪心】

题目传送门:https://codeforces.com/contest/1036/problem/B 被这道题坑了,说白了还是菜. 贪心策略是先斜对角从(0,0)走到(n,n),然后往右拐(分奇偶考虑)[若n>m,swap(n,m)] 理论上是画画图,知道切入点是奇偶性后,就能想清楚了 #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<q

CF 1036B Diagonal Walking v.2——思路

题目:http://codeforces.com/contest/1036/problem/B 比赛时只能想出不合法的情况还有走到终点附近的方式. 设n<m,不合法就是m<k.走到终点方式就是先斜着走了n*n的正方形,然后一拐一拐地走到终点或距离终点仅剩一个格子的地方.走到终点后可以走任意偶数步,走出去终点又走回来这样. 然后开始超麻烦地考虑,比如走很多横着的步使得起点向终点移动一些,然后-- 最后发现过不了样例. 赛后看看别人的代码,发现异常简单.就是到上面那一步之后, 如果一拐一拐地正好走

codeforces cf edu round#50 B. Diagonal Walking v.2

思路:当m > k时输出-1(设m是较大的数),当m-n是奇数时有一步不能走对角线所以k--,当走对角线可以直接到达终点,如果剩余的步数是奇数则有两步不能走对角线所以k - 2.(画图观察规律) #include<bits/stdc++.h> using namespace std; typedef long long ll; int main() { int q; scanf("%d",&q); while(q--) { ll n,m,k; scanf(&q

CF 1036 B Diagonal Walking v.2 —— 思路

题目:http://codeforces.com/contest/1036/problem/B 题意:从 (0,0) 走到 (n,m),每一步可以向八个方向走一格,问恰好走 k 步能否到达,能到达则输出最多能走多少斜步: 自己想得太复杂了... 首先,判断 -1 就看横纵距离中的较大值是否大于 k ,因为最少走 max(n,m) 步可以到达: 设 m > n: 如果 m - n 为奇数,那么显然会有一步必须直着走,那么 k --: 这里可以通过走法来调节剩余步数的奇偶,就是直着走过去或者拐一下走

Codeforces 1093C (思维+贪心)

题面 传送门 题目大意: 有一个长n(n为偶数)的序列a 已知a满足 \(a_1≤a_2≤?≤a_n\) 给出一个长度为\(\frac{n}{2}\) 的序列b,定义\(b_i=a_i+a_{n-i+1}\) 求出序列a (输出任意一种答案即可) 分析 为了保证序列不下降,我们采用贪心的思想,先假设\(a_i=a_{i-1}\),这样给后面的数留有的余地更大 然后计算出\(a_{n-i+1}=b_i-a_i\),如果\(a_{n-i+1}>a_{n-i+1+1}\),即不满足不下降的条件,则进行

B. Diagonal Walking v.2

链接 [https://i.cnblogs.com/EditPosts.aspx?opt=1] 题意 二维平面从原点出发k步,要到达的点(x,y),每个位置可以往8个方位移动,问到达目的地最多可以走多少斜路 如果不可以到达输出-1: 分析 找规律,看代码自己琢磨 代码 #include<bits/stdc++.h> using namespace std; #define ll long long int main(){ ios::sync_with_stdio(false); cin.tie

Codeforces 413C Jeopardy!(贪心)

题目链接:Codeforces 413C Jeopardy! 题目大意:给出n个关卡,每个关卡闯关成功会得到相应的分数,有m个关卡闯关成功之后,可以选择不加上该关卡的分,而是将已有的分数翻倍,现在有一位选手已经有能力闯过所有的关卡,问说他能得到的最大分数是多少. 解题思路:贪心,将可以翻倍的关卡放在后面比,不能翻倍的关卡放在前面比,然后在按照关卡分数大的先比,如果该关卡分数可以翻倍,就判断是当前关卡的分数高还是已有的分数高. #include <cstdio> #include <cst

Codeforces Round #459 (Div. 2) C 思维,贪心 D 记忆化dp

Codeforces Round #459 (Div. 2) C. The Monster 题意:定义正确的括号串,是能够全部匹配的左右括号串. 给出一个字符串,有 (.). ? 三种字符, ? 可以当作 ( 可 ) . 问这个字符串有多少个子串是正确的括号串. tags:好考思维,想不到.. 预处理出每个字符向左向右最多可以匹配到哪里,再 O(n*n) 枚举所有区间,看是否符合条件. // C #include<bits/stdc++.h> using namespace std; #pra

Balanced Ternary String CodeForces - 1102D (贪心+思维)

You are given a string ss consisting of exactly nn characters, and each character is either '0', '1' or '2'. Such strings are called ternary strings. Your task is to replace minimum number of characters in this string with other characters to obtain