EOJ3724求和公式求解

wyloveyxb 2019-07-28 06:41:53



https://acm.ecnu.edu.cn/problem/3724/
使用如下代码,第12个测试用例就超时了,求各位大神解答
#include<iostream>
#include<algorithm>
using namespace std;
long long n;
int q;
int main()
{
cin>>n>>q;
for(int turn=0;turn<q;turn++)
{
long long sx,sy;
long long ex,ey;
cin>>sx>>sy;
cin>>ex>>ey;
int sum=0;
long long gx=ex-sx;
long long gy=ey-ex;
if(gx<=gy)
{
for(long long i=sx;i<=ex;i++)
{
long long y1=i;
long long y2=-i+(n-1);
if(y1>=sy&&y1<=ey)
{
sum++;
}
if(y2>=sy&&y2<=ey)
{
sum++;
}
if(n%2!=0)
{
if(y1==y2)
sum--;
}
}
}
else
{
for(long long i=sy;i<=ey;i++)
{
long long x1=i;
long long x2=(n-1)-i;
if(x1>=sx&&x1<=ex)
{
sum++;
}
if(x2>=sx&&x2<=ex)
{
sum++;
}
if(n%2!=0)
{
if(x1==x2)
sum--;
}
}
}
cout<<sum<<endl;
}
return 0;
}
...全文
208 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
wyloveyxb 2019-08-01
  • 打赏
  • 举报
回复
引用 13 楼 真相重于对错的回复:
你的代码有问题
对,有问题,而且用的最笨比的方法写的
真相重于对错 2019-08-01
  • 打赏
  • 举报
回复
你的代码有问题
wyloveyxb 2019-07-31
  • 打赏
  • 举报
回复
用上面老哥的思路,过了test12了,但是test42却wrong answer了

#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
ll n;
struct Point{
	ll x;
	ll y;
	Point(){
	}
	Point(ll xx,ll yy):x(xx),y(yy){
	}
	bool operator==(const Point other) const
	{
		if(x==other.x&&y==other.y)
			return true;
		else
			return false;
	}
	bool operator<(const Point other) const
	{
		return x<other.x;
	}
};
set<Point> p_set1,p_set2;//用来记录交点
//检查y=x的交点,并记录下来 
int check1(Point p1,Point p2)
{
	if(p1.x>=p1.y&&p1.x<=p2.y)
		p_set1.insert(Point(p1.x,p1.x));
	if(p2.x>=p1.y&&p2.x<=p2.y)
		p_set1.insert(Point(p2.x,p2.x));
	if(p1.y>=p1.x&&p1.y<=p2.x)
		p_set1.insert(Point(p1.y,p1.y));
	if(p2.y>=p1.x&&p2.y<=p2.x)
		p_set1.insert(Point(p2.y,p2.y));
	return p_set1.size();
}
//检查y=n-1-x,并将交点记录下来
int check2(Point p1,Point p2)
{
	ll y=n-1-p1.x;
	if(y>=p1.y&&y<=p2.y)
		p_set2.insert(Point(p1.x,y));
	y=n-1-p2.x;
	if(y>=p1.y&&y<=p2.y)
		p_set2.insert(Point(p2.x,y));
	ll x=n-1-p1.y;
	if(x>=p1.x&&x<=p2.x)
		p_set2.insert(Point(x,p1.y));
	x=n-1-p2.y;
	if(x>=p1.x&&x<=p2.x)
		p_set2.insert(Point(x,p2.y));
	return p_set2.size();			
} 
int main()
{
	cin>>n;
	int q;
	cin>>q;
	while(q--)
	{
		Point p1,p2;
		cin>>p1.y>>p1.x;
		cin>>p2.y>>p2.x;
		p_set1.clear();
		p_set2.clear();
		ll len1=0,len2=0;
		if(check1(p1,p2)==2)
		{
			set<Point>::iterator it=p_set1.begin();
			it++;
			len1=(*it).x-p_set1.begin()->x+1;
		}
		else 
			len1=p_set1.size(); 
		if(check2(p1,p2)==2)
		{
			set<Point>::iterator it=p_set2.begin();
			it++;
			len2=(*it).x-p_set2.begin()->x+1;
		}
		else 
			len2=p_set2.size(); 
		//若是奇数去除中心点
		if(n%2==1)
		{
			ll c=(n-1)/2;
			if(p_set1.count(Point(c,c)))
				len1--;	
		}
		cout<<len1+len2<<endl;
	}
	return 0;
}
wyloveyxb 2019-07-31
  • 打赏
  • 举报
回复
引用 9 楼 真相重于对错 的回复:
[quote=引用 8 楼 wyloveyxb 的回复:] [quote=引用 7 楼 真相重于对错 的回复:] 这个问题其实可以简化为两条直线穿越一个矩形,并求出其线段在x轴上投影的长度
那这样是不是还要判断矩形区域被几条直线区域穿越,大佬能说的详细点吗? [/quote] 判断区域,不就是判断矩形的4条边和这两条对角线的交点吗?[/quote]
引用 9 楼 真相重于对错 的回复:
[quote=引用 8 楼 wyloveyxb 的回复:] [quote=引用 7 楼 真相重于对错 的回复:] 这个问题其实可以简化为两条直线穿越一个矩形,并求出其线段在x轴上投影的长度
那这样是不是还要判断矩形区域被几条直线区域穿越,大佬能说的详细点吗? [/quote] 判断区域,不就是判断矩形的4条边和这两条对角线的交点吗?[/quote] 哈哈,不过时间复杂度降低了!!
wyloveyxb 2019-07-31
  • 打赏
  • 举报
回复
引用 9 楼 真相重于对错 的回复:
[quote=引用 8 楼 wyloveyxb 的回复:] [quote=引用 7 楼 真相重于对错 的回复:] 这个问题其实可以简化为两条直线穿越一个矩形,并求出其线段在x轴上投影的长度
那这样是不是还要判断矩形区域被几条直线区域穿越,大佬能说的详细点吗? [/quote] 判断区域,不就是判断矩形的4条边和这两条对角线的交点吗?[/quote] 反而觉得这样越麻烦了呢
真相重于对错 2019-07-30
  • 打赏
  • 举报
回复
引用 8 楼 wyloveyxb 的回复:
[quote=引用 7 楼 真相重于对错 的回复:] 这个问题其实可以简化为两条直线穿越一个矩形,并求出其线段在x轴上投影的长度
那这样是不是还要判断矩形区域被几条直线区域穿越,大佬能说的详细点吗? [/quote] 判断区域,不就是判断矩形的4条边和这两条对角线的交点吗?
wyloveyxb 2019-07-30
  • 打赏
  • 举报
回复
引用 7 楼 真相重于对错 的回复:
这个问题其实可以简化为两条直线穿越一个矩形,并求出其线段在x轴上投影的长度
那这样是不是还要判断矩形区域被几条直线区域穿越,大佬能说的详细点吗?
真相重于对错 2019-07-30
  • 打赏
  • 举报
回复
这个问题其实可以简化为两条直线穿越一个矩形,并求出其线段在x轴上投影的长度
Italink 2019-07-29
  • 打赏
  • 举报
回复

#include <iostream>
#include<iostream>
using namespace std;
int main(){
long long n,q,a,b,c,d,count;
cin>>n>>q;
for(int i=0;i<q;i++){
count=0;
cin>>a>>b>>c>>d;
for(int j=a;j<=c;j++){
if(b<=j&&j<=d)
count++;
if(b<=n-j-1&&n-j-1<=d)
count++;
}
cout<<count<<endl;
}

}
wyloveyxb 2019-07-29
  • 打赏
  • 举报
回复
引用 2 楼 Italink 的回复:

#include <iostream>
#include<iostream>
using namespace std;
int main(){
	long long n,q,a,b,c,d,count;
	cin>>n>>q;
	for(int i=0;i<q;i++){
		count=0;
		cin>>a>>b>>c>>d;
		for(int j=a;j<=c;j++){
			if(b<=j&&j<=d)
				count++;
			if(b<=n-j-1&&n-j-1<=d)
				count++;
		}
		cout<<count<<endl;
	}
	
}
还是卡在test12上了,报的错是超时,并不是wrong answer
Italink 2019-07-29
  • 打赏
  • 举报
回复

#include<iostream>
using namespace std;
int main() {
long long n, q, a, b, c, d, count;
cin >> n >> q;
for (int i = 0; i < q; i++) {
count = n % 2 ? -1 : 0;
cin >> a >> b >> c >> d;
for (int j = a; j <= c; j++) {
if (b <= j && j <= d)
count++;
if (b <= n - j - 1 && n - j - 1 <= d)
count++;
}
cout << count << endl;
}
return 0;
}

wyloveyxb 2019-07-29
  • 打赏
  • 举报
回复
引用 1 楼 真相重于对错 的回复:
你的程序有问题, 只有对角线上有数,所以只要求区域里面在对角上的点就可以, 对角线上也就是 x=y(x=横坐标 ,y=纵坐标) x+y=n 还有中心点不要算两次 x=y&&x+y=n
我判断了如果算出阿来的坐标相等 个数就减一了呀
wyloveyxb 2019-07-29
  • 打赏
  • 举报
回复
#2 的哥们 第12个用例还是过不了
真相重于对错 2019-07-28
  • 打赏
  • 举报
回复
你的程序有问题, 只有对角线上有数,所以只要求区域里面在对角上的点就可以, 对角线上也就是 x=y(x=横坐标 ,y=纵坐标) x+y=n 还有中心点不要算两次 x=y&&x+y=n

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧