补题报告3

猜左数第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;

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值