山再高,往上爬,总能登顶;
路再长,走下去,定能到达。
趾压板矩阵
题目描述
第二天早晨,跑男队员们来到了风景秀丽的扬州瘦西湖,刚下车他们全都尖叫起来,没错,就是他们最怕的“趾压板”:
一块超级大的趾压板被分成了n行n列,每个小格子上都有一个数字。游戏规则是:观察一段时间后,把所有的数字拿掉,分别抽取一个行号i和列号j,说出这个位置上原来的数字是多少,如果不能说出正确的值,就要接受处罚,光脚从左上角1沿着顺序从小到大走到这个数字所在位置。
“捡漏王”王祖蓝思考了一会,马上找到了其中的奥秘,你呢?
输入
输入共一行,包含三个整数n,i,j,每两个整数之间用空格隔开,分别表示矩阵大小、待求的数所在的行号和列号。
输出
输出共一行,包含一个整数,表示相应矩阵中第i行和第j列的数。
Sample Input
7 4 3
Sample Output
18
Hint
对于50%的数据,1≤n≤100;
对于100%的数据,1≤n≤30,000,1≤i≤n,1≤j≤n。扫描二维码关注公众号,回复: 11138684 查看本文章
题目分析
这题的数据是30000,那么打表就不行了,一个是内存会炸第二1e8也跑不出来。
这样就要有一个法则来去寻找了
法则如下
1.在第几斜行
比如1 是在第一行
23是在第二行
456在第三行
2.确定该行的最大值和位置
3.移动坐标,寻求答案
AC时间到
#include<algorithm>
#include<iostream>
#include<string.h>
#include <iomanip>
#include<stdio.h>
#include<utility>
#include<vector>
#include<string>
#include<math.h>
#include<cmath>
#include<queue>
#include<stack>
#include<deque>
#include<map>
#pragma warning(disable:4244)
#define PI 3.1415926536
#pragma GCC optimize(2)
#define accelerate cin.tie(NULL);cout.tie(NULL);ios::sync_with_stdio(false);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll ll_inf = 9223372036854775807;
const int int_inf = 2147483647;
const short short_inf = 32767;
const char char_inf = 127;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline ll read() {
ll c = getchar(), Nig = 1, x = 0;
while (!isdigit(c) && c != '-')c = getchar();
if (c == '-')Nig = -1, c = getchar();
while (isdigit(c))x = ((x << 1) + (x << 3)) + (c ^ '0'), c = getchar();
return Nig * x;
}
inline void out(ll a) {
if (a < 0)putchar('-'), a = -a;
if (a >= 10)out(a / 10);
putchar(a % 10 + '0');
}
ll qpow(ll x, ll n, ll mod) {
ll res = 1;
while (n > 0) {
if (n & 1)res = (res * x) % mod;
x = (x * x) % mod;
n >>= 1;
}
return res;
}
#define Floyd for(int k = 1; k <= n; k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)
#define read read()
int tx, ty, n;
void fun(int x, int y)//一直往下降,降到边界
{
tx = x, ty = y;
while (tx != n && ty != 1)tx++, ty--;
return;
}
int main()
{
bool SW = 0;
n = read;
int num = 0;
int x = read, y = read;
fun(x, y);
int f = 0;
if (ty == 1)f = tx;//判断在第几层(斜行)
else f = n - 1 + ty;
if (f > n)
{//当n为7时,每一层的增长规律如下1 2 3 4 5 6 7 6 5 4 3 2 1
int T = n - 1;
num = (n + 1) * n / 2;
for (int i = n + 1; i <= f; i++)
num += T--;
}
else num = (f + 1) * f / 2;
if (f % 2)//奇数层往上走是数是变小的
{
while (tx != x && ty != y)
{
num--;
tx--;
ty++;
}
cout << num << endl;
}
else//偶数曾往下走是变小的
{
while (tx != 1 && ty != n)
{
ty++, tx--;
}
while (tx != x && ty != y)
{
num--;
tx++, ty--;
}
cout << num << endl;
}
}
By-轮月