poj3685 二分答案+找规律

标签: acm 二分搜索
11人阅读 评论(0) 收藏 举报
分类:

题目:

Matrix
Time Limit: 6000MS Memory Limit: 65536K
Total Submissions: 7915 Accepted: 2388

Description

Given a N × N matrix A, whose element in the i-th row and j-th column Aij is an number that equals i2 + 100000 × i + j2 - 100000 × j + i × j, you are to find the M-th smallest element in the matrix.

Input

The first line of input is the number of test case.
For each test case there is only one line contains two integers, N(1 ≤ N ≤ 50,000) and M(1 ≤ M ≤ N × N). There is a blank line before each test case.

Output

For each test case output the answer on a single line.

题意:(来自vj)有一个N阶方阵 第i行,j列的值Aij =i2 + 100000 × i + j2 - 100000 × j + i × j,需要找出这个方阵的第M小值.


思路: 由A[i][j] = i2 + 100000 × i + j2 - 100000 × j + i × j 得:

A[i+1][j] = A[i][j] + (2*i + j + 1 + 100000);(同一列递推式)

A[i][j+1] = A[i][j] + (2*j + i + 1 - 100000); (同一行递推式)

由此可知,在列方向上,矩阵单调递增,而在行方向上上,当(2*j + i + 1)> 100000 时,递增,反之递减。

于是我们可以首先二分答案(即第m大的数),然后再在每一列中二分搜索有多少数要小于等于该值,将每一列的值求和即可得出与第一次二分答案得到的数的规律。

代码:

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<set>
#define sd(x) scanf("%d",&x)
#define ss(x) scanf("%s",x)
#define sc(x) scanf("%c",&x)
#define sf(x) scanf("%f",&x)
#define slf(x) scanf("%lf",&x)
#define slld(x) scanf("%lld",&x)
#define me(x,b) memset(x,b,sizeof(x))
#define pd(d) printf("%d\n",d);
#define plld(d) printf("%lld\n",d);
#define eps 1.0E-8
// #define Reast1nPeace

typedef long long ll;

using namespace std;

const ll INF = 0x3f3f3f3f3f3f3f;

ll x,y;

ll get(ll i,ll j){
	return i*i + 100000*i + j*j -100000*j + i*j; 
}

bool judge(ll num){
	ll sum = 0;
	for(int j = 1 ; j<=x ; j++){
		ll l = 1 ; ll r = x;
		ll ans = 0;
		while(l<=r){
			ll mid = (l+r)/2;
			if(get(mid,j) <= num){
				ans = mid;
				l = mid+1;
			}
			else{
				r = mid-1;
			}
		}
		sum += ans;
	}
	return sum >= y;
}

int main(){
#ifdef Reast1nPeace
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif
	ios::sync_with_stdio(false);
	int T;
	cin>>T;
	while(T--){
		cin>>x>>y;
		
		ll l = -INF; ll r = INF;
		ll ans;
		while(l<=r){
			ll mid = (l+r)/2;
			if(judge(mid)){
				ans = mid;
				r = mid-1;
			}
			else{
				l = mid+1;
			}
		}
		cout<<ans<<endl;
	} 
	return 0;
}
查看评论

poj3685 Matrix 二分答案

可以看出每一列的数字都是单调的,于是就能在每一列用二分来计算一个值在这个矩阵中的排名。 二分答案+验证即可。 #include #include #include #include #in...
  • Sd_Invol
  • Sd_Invol
  • 2013-07-29 01:23:07
  • 660

poj3685Matrix(二分)

看到题完全没想到是二分(太弱,太渣了),别人告诉本弱这道题是二分依旧不会做。 思路:二分答案ans,然后枚举j,然后再二分i,求出矩阵中小于等于ans元素的个数…… 注意二分时如果l或r出现负数,...
  • abc13068938939
  • abc13068938939
  • 2016-08-23 09:45:54
  • 250

POJ3685-Matrix

观察此题给出的条件 i^2 + 100000 × i + j^2 - 100000 × j + i × j可知,这个函数值随i的增大而增大,因此在写二分条件的时候可以从每一列开始寻找小于等于mid的值...
  • Walton_
  • Walton_
  • 2016-08-02 11:39:05
  • 103

深入理解二分查找(二、二分答案)

二分答案     如果已知候选答案的范围[min,max],有时候我们不必通过计算得到答案,只需在此范围内应用“二分”的过程,逐渐靠近答案(最后,得到答案)! 一、何时可以使用“二分答...
  • ocean_62
  • ocean_62
  • 2016-10-26 12:45:30
  • 676

二分答案

二分答案  (2011-09-21 18:18:21) 标签:  杂谈   from:http://www.cnblogs.com/saltless/archive/201...
  • u012019622
  • u012019622
  • 2014-02-27 12:50:23
  • 794

51Nod-1799-二分答案

ACM模版描述题解我们知道二分的过程中,不管是否有序,对二分结果产生直接影响的是 mid 位置的数据,而其他无关位置的数据就随意一些了,所以我们只需要先通过一边二分求出左右 l 和 r 的更新次数,然...
  • f_zyj
  • f_zyj
  • 2017-05-30 21:05:58
  • 524

【模板+讲解】二分答案

【模板+讲解】二分答案 !阅读须知||阅读本博文前笔者认为读者已经学会(或了解)了: 1.基础语言与算法 2.标准二分法(二分思想) 3.二分查找 定义二分答案与二分查找类似,即...
  • Mashiro_ylb
  • Mashiro_ylb
  • 2017-11-07 16:17:59
  • 409

二分查找与二分答案

二分 •主要用于在一个单调的函数中查询某值 • 连续函数的情况: • 若当前查找的区间是 [l, r] ,查询的值是 y ,函数单增 • 设 mid = (l + r) / 2 若 f(mid) •...
  • qq_37654726
  • qq_37654726
  • 2017-12-27 21:28:42
  • 79

hihoCoder 1139 二分·二分答案

#include using namespace std; struct edge{ int x,w; }; int n,m,k,t; vector v[10005]; int vis[1...
  • piaocoder
  • piaocoder
  • 2015-08-07 09:41:48
  • 629

Poj 3685 Matrix

题目:http://poj.org/problem?id=3685
  • Zhuhuangjian
  • Zhuhuangjian
  • 2014-05-14 19:12:03
  • 1232
    个人资料
    持之以恒
    等级:
    访问量: 4408
    积分: 499
    排名: 10万+
    文章存档