猜左数第k个0位置 - 简易版 - 交互题(选做)
这是一个互动问题。
这是问题的简易版。与困难版不同的是,在简易版中 和查询次数限制为 。
小可正在玩一个电脑游戏。在这个游戏中,一个由 0 和 1 组成的数组被隐藏起来。如果小可猜中了左数第 个 0 的位置 次,那么他就赢了。
小可可以提出不超过 次以下类型的请求:
? l r ,表示求出至 l至r位置上所有元素的和l包括和r。
在本题(简易版)中,由于 总是存在,因此本段并没有实际意义。为了增加游戏的趣味性,每个被猜中的 0 都会变成 1,然后游戏在变化后的数组中继续进行。更直观地说,如果第 个零的位置是 ,那么在小可猜出这个位置后,数组中第 个元素将从 替换为 。当然,这个特性只对 有影响。帮助小可赢得游戏吧!
互动过程
首先,你的程序必须读取两个整数n和t。
然后是t行,每行包含一个整数k 。可以保证的是,在发送请求时,数组
至少包含k个零。为了获取下一个值 ,必须输出当前值 的答案。在此之后,你不能再提出超过20次请求。
使用以下格式输出答案(它不是请求,不计入中):! x,表示第k个0的位置。
数组中的位置从左到右从1到n包括在内。打印出t个答案后,程序应立即退出。
在这个任务中,交互器是非自适应的。这意味着在同一个测试中,隐藏数组和查询不会改变。
如果超过了请求次数,则会显示错误答案。
如果你没有打印任何内容或忘记刷新输出缓冲区,可能会收到超过内存超限的判断。要清空输出缓冲区,需要在查询输出和行结束符之后立即执行以下操作:
fflush(stdout) 或 C ++ 中的 cout.flush();
输入样例
输出样例
6 1
2
2
1
1
0
0
? 4 6
? 1 1
? 1 2
? 2 2
? 5 5
! 5
#include<bits/stdc++.h>
using namespace std;
int t,n,k,x;
int main(){
cin>>n>>t;
cin>>k;
int l=1,r=n;
while(l<r){
int mid=(l+r)/2;
cout<<"?"<<1<<" "<<mid<<"\n";
int x;
cin>>x;
if(mid-x<k){
l=mid+1;
}
else{
r=mid;
}
}
cout<<"! "<<l;
return 0;
}
去还是不去?
3S 512M
问题描述
小可睡过头了,不知道自己是否赶得上来上第一节课。为此,他需要知道从家到学校所需的最短时间。
小可居住的城市是一个大小为n*m的长方形区域。每个小格(i,j)用一个数字aij表示:
数字-1表示禁止通过该单元;
数字0表示该单元格小可可以穿过。
数字x表示该单元包含一个花费为x的传送门入口。有入口的单元格也被视为可以直接穿过的单元格。
小可可以从任何一个传送门入口到达其他任何一个传送门入口,而从入口 到达入口 的时间
相当于它们的花费总和aij+axy。
除了在传送门之间移动,迪马还可以在时间 内在相邻的未被禁止的单元格之间移动。特别是,他可以进入一个有传送门的单元格而不使用传送门,就当正常通行的单元格用。
最初,小可位于左上方的单元格 ,而学校位于右下方的单元格 。
注:代码时超了!
#include<bits/stdc++.h>
using namespace std;
const long long inf=1e18;
const int maxn=2e3+5;
long long n,m,w,a[maxn][maxn],cnt;
long long dis[maxn][maxn],sum,flag;
bool vis[maxn][maxn];
int fx[4]={0,0,1,-1};
int fy[4]={1,-1,0,0};
struct stu{
int x,y;
};
void bfs(int s,int t){
long long ans=inf;
queue<stu> p;
memset(dis,0,sizeof(dis));
memset(vis,0,sizeof(vis));
p.push(stu{s,t});
vis[s][t]=1;
if(a[s][t]!=0){
ans=a[s][t];
}
while(!p.empty()){
stu t=p.front();
p.pop();
int x=t.x,y=t.y;
for(int i=0;i<4;i++){
cnt++;
int xx=x+fx[i],yy=y+fy[i];
if(a[xx][yy]!=-1&&!vis[xx][yy]){
dis[xx][yy]=dis[x][y]+w;
if(a[xx][yy]!=0){
ans=min(ans,dis[xx][yy]+a[xx][yy]);
}
vis[xx][yy]=1;
p.push(stu{xx,yy});
}
}
}
if(ans==inf){
flag++;
}
sum+=ans;
}
int main(){
scanf("%lld %lld %lld",&n,&m,&w);
memset(a,-1,sizeof(a));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%lld",&a[i][j]);
}
}
bfs(n,m);
bfs(1,1);
cout<<cnt<<"\n";
if(dis[n][m]==0){
if(flag){
printf("-1");
}
else{
printf("%lld",sum);
}
}
else{
if(!flag){
printf("%lld",min(sum,dis[n][m]));
}
else{
printf("%lld",dis[n][m]);
}
}
return 0;
}