首页 > 其他分享 >COCI2011-2012#3 ROBOT 题解

COCI2011-2012#3 ROBOT 题解

时间:2024-04-07 09:04:38浏览次数:27  
标签:yi 题解 lq ROBOT long nx ny COCI2011 ans

洛谷题面

部分分做法

直接依照题意模拟即可。
可以获得 \(48\) 分的好成绩。

#include<bits/stdc++.h>
#define int long long
using namespace std;
long long n,m;
struct node{
	long long x;
	long long y;
}point[100005];
long long robotx=0,roboty=0;
long long query(){
	long long sum=0;//计算(point[i].x,point[i].y)和(robotx,roboty)的曼哈顿距离 
	for(int i=1;i<=n;i++){
		sum=sum+abs(point[i].x-robotx)+abs(point[i].y-roboty);
	}
	return sum;
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>point[i].x>>point[i].y;
	}
	while(m--){
		char opt;
		opt=getchar();
		if(opt=='S'){
			roboty++;
		}
		if(opt=='J'){
			roboty--;
		}
		if(opt=='I'){
			robotx++;
		}
		if(opt=='Z'){
			robotx--;
		}
		cout<<query()<<endl;
	}
}

代码复杂度为 \(O\left ( n \times m\right )\),超时但能冲掉不少数据点。

正解

如何优化呢?我的做法是前缀和。我们一开始就把当前的曼哈顿之和先算出来,记录行和列上的控制点的个数,对行和列分别进行前缀和预处理,用 \(x\) 和 \(y\) 记录当前机器人的坐标,\(ans\) 是曼哈顿距离的总和。

我们每次得到一个操作,便根据情况分析一下,用很简单的操作即可得到答案。

设记录操作种类的字符为 \(opt\),数组 \(lq\) 为列的前缀和,\(hq\) 为行的前缀和,\(l\) 为每列的操作点的个数,\(h\) 为每行操作点的个数,\(n\) 为点的总数。

  • \(opt = S\) 时,\(ans=ans+lq_y-(n-lq_y)\)。

  • \(opt = J\) 时,\(ans=ans+n-lq_y+l_y-(lq_y-l_y)\)。

  • \(opt = I\) 时,\(ans=ans+hq_x-(n-hq_x)\)。

  • \(opt = Z\) 时,\(ans=ans+n-hq_x+h_x-(hq_x - h_x)\)

前缀和此题在洛谷 32MB 的空间下会有 MLE 的风险,所以 @wangzihang2012 的二分是好方法,但我不会。

#include<bits/stdc++.h>//都开long long会炸掉
using namespace std;
const long long yi=1e6;
long long hq[2000005],lq[2000005],h[2000005],l[2000005];
long long x,y,n,m,i,j,k,s,nx,ny,ans;
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>x>>y;
		h[x+yi]++;
		l[y+yi]++;
		ans=ans+abs(x-0)+abs(y-0);
	}
	for(int i=-1000000+1;i<=1000000;i++){
		lq[yi+i]=lq[i-1+yi]+l[i+yi];
		hq[yi+i]=hq[i-1+yi]+h[i+yi];
	}
	nx=0;
	ny=0;
	for(int i=1;i<=m;i++){
		char ch;
		cin>>ch;
		if(ch=='S'){
			ans=ans+lq[ny+yi];
			ans=ans-(n-lq[ny+yi]);
			ny++;
		}
		if(ch=='J'){
			ans=ans-(lq[ny+yi]-l[ny+yi]);
			ans=ans+(n-lq[ny+yi]+l[ny+yi]);
			ny--;
		}
		if(ch=='I'){
			ans=ans+hq[nx+yi];
			ans=ans-(n-hq[nx+yi]);
			nx++;
		}
		if(ch=='Z'){
			ans=ans-(hq[nx+yi]-h[nx+yi]);
			ans=ans+(n-(hq[nx+yi]-h[nx+yi]));
			nx--;
		}
		cout<<ans<<endl;
	}
}

全 MLE /ll 提交记录

但是前缀和改成 int 其他不变就可以 AC 啦! AC 记录

#include<bits/stdc++.h>
using namespace std;
const int yi=1e6;
int hq[2000005],lq[2000005];
int h[2000005],l[2000005];
int x,y,n,m,k,s,nx,ny;
long long ans;
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>x>>y;
		h[x+yi]++;
		l[y+yi]++;
		ans=ans+abs(x-0)+abs(y-0);
	}
	for(int i=-1000000+1;i<=1000000;i++){
		lq[yi+i]=lq[i-1+yi]+l[i+yi];
		hq[yi+i]=hq[i-1+yi]+h[i+yi];
	}
	nx=0;
	ny=0;
	for(int i=1;i<=m;i++){
		char ch;
		cin>>ch;
		if(ch=='S'){
			ans=ans+lq[ny+yi];
			ans=ans-(n-lq[ny+yi]);
			ny++;
		}
		if(ch=='J'){
			ans=ans-(lq[ny+yi]-l[ny+yi]);
			ans=ans+(n-lq[ny+yi]+l[ny+yi]);
			ny--;
		}
		if(ch=='I'){
			ans=ans+hq[nx+yi];
			ans=ans-(n-hq[nx+yi]);
			nx++;
		}
		if(ch=='Z'){
			ans=ans-(hq[nx+yi]-h[nx+yi]);
			ans=ans+(n-(hq[nx+yi]-h[nx+yi]));
			nx--;
		}
		cout<<ans<<endl;
	}
}

感谢观看。

标签:yi,题解,lq,ROBOT,long,nx,ny,COCI2011,ans
From: https://www.cnblogs.com/zxcqwq/p/18118314

相关文章

  • 不知道什么题的题解
    多组测试数据,问你满足\(lcm\left(x,y\right)=n\)的数对\(\left(x,y\right)\)的数量。由于唯一分解定理,我们不妨令\(x=p_{1}^{a_1}\timesp_{2}^{a_2}\times\cdots\timesp_{i}^{a_i}\),同理,\(y=p_{1}^{b_1}\timesp_{2}^{b_2}\times\cdots\timesp_{i}^......
  • 第33次CSP认证500分题解
    近年来最简单的一次\(CSP\)认证,\(3\)个小时现场满分直接拿下。1、没啥好说的,直接开桶拿下。#include<bits/stdc++.h>usingnamespacestd;#defineN1000010template<classT>inlineTread(T&a){Tx=0,s=1;charc=getchar();while(!isdigi......
  • ABC348F 题解
    一些注意点:一看到这种题就应该往bitset的方向想。如果用bitset,就应该跳脱之前的思维,尝试从最朴素的暴力重新想起。看到这道题,发现直接做非常的不可做的样子,考虑bitset。我们可以先枚举左端点\(l\)。这样,当我们枚举\(j\)时,对于所有的\(k\)使得\(a_{k,j}=a_......
  • 网站使用CDN出现ttf woff等字体跨域问题解决方案
    如果cdn域名+资源路径是可以通过浏览器url地址栏打开的那么一般是因为nginx配置的原因,找到nginx的配置文件添加以下代码:# 允许指定域名访问;location ~ .*.(eot|ttf|ttc|otf|eot|woff|woff2|svg)(.*) { add_header Access-Control-Allow-Origin http(s)://......
  • arch安装教程+部分问题解决
    arch安装教程+部分问题解决网络配置#进入iwctliwctl#获取device名称我这里是wlan0,后面注意wlan0替换成你自己devicedevicelist#扫描附近wifistationwlan0scan#获取所有可连接wifi名字stationwlan0get-networksstationwlan0connect[wifi名]#输入密码......
  • CF1149D Abandoning Roads 题解
    Description一张\(n\)个点\(m\)条边的无向图,只有\(a,b\)两种边权(\(a<b\)),对于每个\(i\),求图中所有的最小生成树中,从\(1\)到\(i\)距离的最小值。\(2\leqn\leq70,n-1\leqm\leq200,1\leqa<b\leq10^7\)。Solution先考虑一个最小生成树是什么样的形态,显然保留边权......
  • P10245 Swimming Pool题解
    P10245SwimmingPool题意给你四条边\(abcd\),求这四条边是否可以组成梯形。思路这显然是一道简单的普通数学题。判断是否能构成梯形只需看四条边是否能满足,上底减下底的绝对值小于两腰之和且大于两腰之差。证明过程如图,\(AB=a\),\(BC=b\),\(CD=c\),\(AD=d\)。过点\(D\)......
  • P10244 String Minimization 题解
    P10244StringMinimization题意给你四个长度为\(n\)的字符串,分别是\(abcd\)。你可以选择一个\(i\)然后交换\(a[i]\)和\(c[i]\),并交换\(b[i]\)和\(d[i]\)。求在\(a\)的字典序尽量小的前提下,\(b\)字典序最小是什么。思路本题并不难。只需要在\(a[i]>c[i]\)......
  • CF1929B Sasha and the Drawing 题解
    CF1929B题意给定一个\(n\timesn\)的正方形,已知正方形最多有\(4\timesn-2\)条对角线,要求要有至少\(k\)条对角线经过至少一块黑色方格,求至少要将几条对角线涂成黑色。分析分类讨论:当\(k<=4\timesn-4\)时,就只需要在上下两侧图就行,所以答案是\([\frac{k}{2}]\)。当......
  • CF301B Yaroslav and Time 题解
    CF301B这不最短路的板子题吗?思路用\(ak\)代表走到第\(k\)点时的可恢复单位时间的值。\(i\)到\(j\)的距离是\(\left(\left|xi-xj\right|+\left|yi-yj\right|\right)\timesd-ak\)。再打一下最短路代码,建议Floyd,因为短。ACCode#include<bits/stdc......