牛客国庆集训派对Day3 A Knight

2024-04-05 20:48

本文主要是介绍牛客国庆集训派对Day3 A Knight,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目:点击打开链接

题意:略。

分析:规律题,打了表半天没找出规律。。。

网友思路:

如果目的点不在第一象限,将其转化到第一象限,且另m>n
若2*n>m>n
    若(n+m)是三的倍数,我可以通过走x个(1,2)和y个(2,1)到达,那么x+2x+2y+y=n+m,得x+y=(n+m)/3;
    若(n+m)%3==1,我可以走这样一步使得(-2,1),使得目的地和起点的曼哈顿距离还是3的倍数,因此答案是(n+m)/3+1
    若(n+m)%3==2,我可以走两步(-2,1),使得目的地和起点的曼哈顿距离还是3的倍数,因此答案是(n+m)/3+2
若m==2*n
   答案是n
若m>2*n
    第一种情况:
    我先尽量走(1,2),直到把n走完,走了n步,若把这时的点看做原点,目的地就是(m-2*n,0),
    转化成起点和目的点在同一直线上的问题
    第二种情况:
    我先走一步(-1,2),然后把(-1,2)当做起点,目的点变成(n+1,m-2)这时在求1+query(n+1,m-2)即可
    答案是两种情况中小的那个
    至于怎么求目的点和起点在同一坐标轴的问题,随便推理一下就知道了

题解:

不妨假设 x>=y>=0。
当 x<=2y 时,定义每一步的冗余值 wi=3-dx-dy,那么∑wi=∑(2-dx)=3*
步数-x-y,显然我们只需要最小化冗余值。我们先只用(+2,+1)(若 x 为奇数则
加一步(+1,+2))走到(x,y’),然后通过将(+2,+1)替换为 2 个(+1,+2)使得
0<=y-y’<3。
若 y-y’=0,则冗余值为 0,显然最小。
若 y-y’=1,则将(+1,+2)替换为(+2,+1)和(-1,+2)或将 2 个(+2,+1)替换为
(+1,+2),(+1,+2),(+2,-1),冗余值为 2,显然最小。(此处需要特判(2,2))
若 y-y’=2,则加上(+2,+1)和(-2,+1),冗余值为 4,由于不存在冗余值为 1
的步,所以最小

 x>2y 时,定义每一步的冗余值 wi=2-dx,那么∑wi=∑(2-dx)=2*步数-x,
显然我们只需要最小化冗余值。我们先只使用(+2,+1)走到(2y,y),然后用
(+2,+1)和(+2,-1)走到(x’,y)使得 0<=x-x’<4。
若 x-x’=0 则冗余值为 0,显然最小

若 x-x’=1 则将之前的(+2,+1)改为(+1,+2)和(+2,-1),冗余值为 1,显然最
小。(此处需要特判(1,0))
若 x-x’=2 则加上(+1,+2)和(+1,-2),冗余值为 2,由 x/2+y 的奇偶性可知
最小。
若 x-x’=3 则加上(+2,+1),(+2,+1),(-1,-2),冗余值为 3,由 x/2+y 的奇偶
性可知最小。
时间复杂度 O(t)

代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#pragma comment(linker, "/STACK:102400000,102400000")
#include<unordered_map>
#include<unordered_set>
#include<algorithm>
#include<iostream>
#include<fstream>
#include<complex>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<iomanip>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cctype>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define pt(a) cout<<a<<endl
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define PI acos(-1.0)
typedef pair<int,int> PII;
const ll mod = 1e9+7;
const int N = 1e6+10;ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qp(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int to[8][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};ll t,n,m,ans;ll gn(int x,int y) { ///max(n,m)<=2的情况特判if(x+y==0) return 0;else if(x+y==1) return 3;else if(x+y==2) return 2;else if(x+y==3) return 1;else return 4;
}ll ln(ll x) {///在同一条线上的情况if(x==0) return 0;else if(x==1) return 3;else if(x%4==0) return x/2;else if(x%2==0) return x/2+1;else if((x/2)%2) return x/2+2;else return x/2+1;
}ll sv(ll x,ll y) {ll s1,s2;s1=y+ln(x-2*y);x-=2,y+=1;///绕一步(规律)if(x<=2) s2=1+gn(x,y);else if(x>2*y) s2=1+y+ln(x-2*y);else if(x==2*y) s2=1+y;else if(x<2*y) s2=1+(x+y)/3+(x+y)%3;return min(s1,s2);///取最小
}int main() {ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);cin>>t;while(t--) {cin>>n>>m;n=abs(n),m=abs(m);if(n<m) swap(n,m);if(n<=2) ans=gn(n,m);else if(n==2*m) ans=m;else if(n>2*m) ans=sv(n,m);else ans=(n+m)/3+(n+m)%3;cout<<ans<<endl;}return 0;
}

 

这篇关于牛客国庆集训派对Day3 A Knight的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/878113

相关文章

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

牛客小白月赛100部分题解

比赛地址:牛客小白月赛100_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ A.ACM中的A题 #include<bits/stdc++.h>using namespace std;#define ll long long#define ull = unsigned long longvoid solve() {ll a,b,c;cin>>a>>b>

牛客小白月赛100(A,B,C,D,E,F三元环计数)

比赛链接 官方讲解 这场比较简单,ABC都很签到,D是个不太裸需要预处理的 B F S BFS BFS 搜索,E是调和级数暴力枚举,F是三元环计数。三元环考的比较少,没见过可能会偏难。 A ACM中的A题 思路: 就是枚举每个边变成原来的两倍,然后看看两短边之和是否大于第三边即可。 不能只给最短边乘 2 2 2,比如 1 4 8 这组数据,也不能只给第二短边乘 2 2 2,比

Knight Moves -uva 简单的BFS遍历

昨天刚学了BFS的遍历,在uva上找了个题敲了出来,感觉还不错,最近敲代码挺有手感的,希望这种状态保持下去 #include<iostream>#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX_SIZE 10 + 5#define LEN 100 + 10using namespace std;in

笔试强训,[NOIP2002普及组]过河卒牛客.游游的水果大礼包牛客.买卖股票的最好时机(二)二叉树非递归前序遍历

目录 [NOIP2002普及组]过河卒 牛客.游游的水果大礼包 牛客.买卖股票的最好时机(二) 二叉树非递归前序遍历 [NOIP2002普及组]过河卒 题里面给的提示很有用,那个马的关系,后面就注意,dp需要作为long的类型。 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息publ

2014暑假集训搜索专题

A - 漫步校园 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Description LL最近沉迷于AC不能自拔,每天寝室、机房两点一线。由于长时间坐在电脑边,缺乏运动。他决定充分利用每次从寝室到机房的时间,在校园里散散步。整个HDU校园呈方形布局,可划

每日OJ_牛客_求和(递归深搜)

目录 牛客_求和(递归深搜) 解析代码 牛客_求和(递归深搜) 求和_好未来笔试题_牛客网 解析代码         递归中每次累加一个新的数,如果累加和大于等于目标,结束递归。此时如果累加和正好等于目标,则打印组合。向上回退搜索其它组合。此题本身就是一个搜索的过程,找到所有的组合。 #include <iostream>#include <cmath>#in

中秋国庆请客喝酒,面子与钱包双赢的红酒选择

平时生活中,总少不了各种聚会,不管是朋友小聚,还是正式的商务宴请,酒都是少不了的,而现在,越来越多的人都喜欢选择红酒来助兴。 喝红酒的人不少,懂红酒的人却不多。有时候真的很尴尬,明明环境菜都不错,就是红酒太难喝,每一口都要鼓足勇气才能下咽。 其实,酒也是饭局的重要组成部分,如果酒不好喝,客人事后也是会暗暗吐槽的。所以,一个好的饭局,酒一定也是好的。 这里说的“好”,既要面子上

牛客《剑指Offer》 -- 数值的整数次方

题目描述 给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。 思路 特别注意负数的情况,出现负数,将其转化为正数然后求倒数。 class Solution {public:double Power(double base, int exponent) {double total = 1;bool flag = false

牛客网《剑指Offer》 二进制中1的个数

题目描述 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。 思路 负数用补码,其实就是求一个数据在计算机中是存储是怎么样子的。用位运算,就能很好实现。 class Solution {public:int NumberOf1(int n) {int count = 0;int flag = 1;while (flag != 0) {if ((n & f