首页 > 其他分享 >Day3 备战CCF-CSP练习

Day3 备战CCF-CSP练习

时间:2024-10-10 14:34:21浏览次数:7  
标签:ver int Day3 花费 cost CCF CSP dp 路由器

Day3

题目描述

目前在一个很大的平面房间里有 \(n\) 个无线路由器,每个无线路由器都固定在某个点上。

任何两个无线路由器只要距离不超过 \(r\) 就能互相建立网络连接。

除此以外,另有 \(m\) 个可以摆放无线路由器的位置。

你可以在这些位置中选择至多\(k\) 个增设新的路由器。

你的目标是使得第 \(1\) 个路由器和第 \(2\)个路由器之间的网络连接经过尽量少的中转路由器。

请问在最优方案下中转路由器的最少个数是多少?

输入格式

第一行包含四个正整数 \(n,m,k,r\)。

接下来 \(n\) 行,每行包含两个整数 \(x_i\) 和 \(y_i\),表示一个已经放置好的无线路由器在\((x_i,y_i)\)
点处。输入数据保证第 \(1\) 和第 \(2\) 个路由器在仅有这 \(n\)个路由器的情况下已经可以互相连接(经过一系列的中转路由器)。

接下来 \(m\) 行,每行包含两个整数 \(x_i\) 和 \(y_i\),表示 \((x_i,y_i)\)点处可以增设一个路由器。

输入中所有的坐标的绝对值不超过 \(10^8\),保证输入中的坐标各不相同。

输出格式

输出只有一个数,即在指定的位置中增设 \(k\) 个路由器后,从第 \(1\) 个路由器到第 \(2\)个路由器最少经过的中转路由器的个数。

数据范围

\(2≤n≤100,1≤k≤m≤100,1≤r≤10^8\)

输入样例:

5 3 1 3
0 0
5 5
0 3
0 5
3 5
3 3
4 4
3 0

输出样例:

2

题目分析

\(bfs+dp\) 或 树形\(dp\)

先建图,将可以通信的两点间连线,因为\(n \le 100\) 所以用邻接矩阵存就行
然后对于图上的点来说,有两类,一类是有花费的,另一类是无花费的。
然后我们求走有花费的点的最短路

这道题很像NOIP 2017 普及组T3 棋盘

其实抽象一下,就是类似于有步数限制的单源汇最短路,但不是所有点都有花费
那么我们就得有两个状态,一个是走到点的单源汇最短路,另一个是花费,且最后结果花费要小于\(k\)
由此想到\(dp\)
\(dp(i , j)\)表示走到\(i\)点,花费点为\(j\)的最小步数
那么对于\(dp(i , j)\)能转移的状态就是他的邻接节点,如果该点有花费,那么转移就得是\(j - - 1\)转移到\(j\)即可
至于遍历图,算单源汇最短路,那就很简单了,数据很小,用\(bfs\)就行


注:一共是\(n + m\)个点所以开\(210\)个空间

C++ 代码

#include <bits/stdc++.h>
#define int long long
#define x first
#define y second

using namespace std;

const int N = 210;

typedef pair<int, int> PII;

int n , m , k , r;
bool is_cost[N];
PII p[N];
bool st[N][N];
int idx , dp[N][N];
bool g[N][N];

bool check(PII a , PII b)
{
    int dist = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
    return r >= dist;
}

void bfs()
{
    memset(dp , 0x3f , sizeof dp);
    dp[1][0] = 0;
    queue<PII> q;
    q.push({1 , 0});
    while(q.size())
    {
        auto t = q.front();
        q.pop();
        int ver = t.x , cost = t.y;
        if(st[ver][cost]) continue;
        st[ver][cost] = true;
        for(int i = 1 ; i <= idx ; i ++)
            if(g[ver][i] && cost + is_cost[i] <= k && !st[i][cost + is_cost[i]] && dp[i][cost + is_cost[i]] >= dp[ver][cost] + 1)
            {
                dp[i][cost + is_cost[i]] = dp[ver][cost] + 1;
                q.push({i , cost + is_cost[i]});
            }
    }
}

signed main()
{
    cin >> n >> m >> k >> r;
    r *= r;
    int a , b;
    for(int i = 1 ; i <= n ; i ++)
    {
        cin >> a >> b;
        p[++ idx] = {a , b};
        is_cost[idx] = false;
    }
    
    for(int i = 1 ; i <= m ; i ++)
    {
        cin >> a >> b;
        p[++ idx] = {a , b};
        is_cost[idx] = true;
    }
    
    for(int i = 1 ; i <= idx ; i ++)
        for(int j = i + 1 ; j <= idx ; j ++)
            if(check(p[i] , p[j]))
                g[i][j] = g[j][i] = 1;
    
    bfs();
    
    int ans = 210;
    
    for(int i = 0 ; i <= k ; i ++)
        ans = min(ans , dp[2][i] - 1);
    cout << ans << '\n';
}

标签:ver,int,Day3,花费,cost,CCF,CSP,dp,路由器
From: https://www.cnblogs.com/mathblog/p/18456315

相关文章

  • [赛记] csp-s模拟8 && csp-s模拟9
    HZOI大作战15pts赛时暴力跳父亲15pts;正解:发现在树上对于向上找大于这个数的操作具有随意划分性,所以考虑倍增,设$f_{i,j}$表示从$i$这个点向上跳$2^j$个比它大的数能跳到哪里,于是我们只需处理出向上跳一个(也就是$f_{i,0}$)的,然后$ST$表预处理即可;具体地,对于......
  • 2024.9.27 模拟赛 CSP5
    模拟赛无T1光题贪心,发现首先让最大的减\(4\),这样最优并且不会涉及向下取整,等到数据范围小了以后直接\(O(n^4)\)暴力枚举。code#include<bits/stdc++.h>usingnamespacestd;inta,b,c,d;intans=1e9;#definemx(x,y)(x>y?(x):(y))#definemi(x,y)(x<y?(x):(y......
  • CSP2024 前集训:多校A层冲刺NOIP2024模拟赛04
    前言T1签了。T2一眼后缀数组板子,但是复杂度是\(O(nq\log(n))\)的,极限数据本地\(4\)秒,但如果您会\(O(n)\)求后缀数组的话就直接过掉了,但赛时数据貌似纯随机,遂可以直接过掉,可以优化成\(O(n^2\log(n)+nq)\)或\(O(n^2\log(n)+q)\)的,赛时想打这个但是怕常熟大和上面区别......
  • csp-s 模拟 10
    csp-s模拟10T1欧几里得的噩梦签到题?如果会线性基的话...由于位数较多直接上线性基肯定是不行的,但是由于题目给出的数在二进制下位数很少,手动模拟一下一个二进制下只有一位的数插入,发现那些二位的数变为了一条边,最后边指向的位数就是它所插入的位置,考虑二位的数其实本质上是......
  • 10.9日牛客CSP-S考试总结
    10.9日牛客CSP-S考试总结T1考场上大概看了一个多小时,想了一个部分分的做法,结果变界判断错误,导致puts("-1");的分也没拿到。T2大部分时间在做这题,想了一个搜索的做法,每次枚举从哪个时刻出发,取了一个较为合适的范围,又加了一个类似于spfa容错的优化。但是因为范围开小就会导致正......
  • CSP 模拟 41
    A邻面合并考虑状压矩形的覆盖情况,因为我们本来就知道这一层的样子,所以二进制就能很好的解决,这一位是1表示从这一位一直是矩形的覆盖,直到遇到原来的0或者另一个1,然后直接暴力转移即可。赛时没有考虑到原来的样子,写了三进制压缩,把矩形覆盖看成栅栏,0表示这个位置没有栅栏,1......
  • 2024CSP前集训10.9
    不想学东西了,,,T1普及题,之前还做过,没啥好说的。T295kmp不对,挂了5分。莫队奇偶性优化还是要加的。对\(s_{i,\dots,n}\)跑kmp,也就是跑了\(n\)遍,答案是: while(m--){ intl=read(),r=read(); intres=0; for(inti=l;i<=r;i++) for(intj=......
  • CSP模拟7
    欠的太多了,就少说点吧T1.median把数组\(a,b,c,d,e\)存到一起,标记类型,然后排序,枚举每个数为中位数,算贡献即可。点击查看代码#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=1e5+107;constintmod=998244353;intn;structlmy{ in......
  • 信息学奥赛复赛复习15-CSP-J2022-01乘方-数据类型、类型转换、数据类型溢出、指数、模
    PDF文档公众号回复关键字:202410091P8813[CSP-J2022]乘方[题目描述]小文同学刚刚接触了信息学竞赛,有一天她遇到了这样一个题:给定正整数a和b,求a^b的值是多少。a^b即b个a相乘的值,例如2^3即为3个2相乘,结果为2×2×2=8“简单!”小文心想,同时很快就写出了......
  • 「闲话」CSP 集训记梦
    一个不写闲话的oier不能证明他是一个oier其实写这个是因为10.5晚上做梦了,所以记录一下建议跳过9.28和10.1部分9.28上午模拟赛。T1一开始搞了个贪心假做法,发现过了大样例,但显然不对吧!也不会其他的解法,先交了一发。然后开始写暴力拍了一手,两千组拍出了个Wa的,手......