新春马拉松题解
2025-2-12 10:27:34
~重点说一下能做的 道题目吧,题解顺序是按照出题人认为的难度写的。
另外 道题目其实是给提高组学生准备的,提高组学生可以上课听我讲解。
然后由于第 个题有些同学使用 软件通过了,所以就也顺便说下,但是的的确确根本就不是你们现在能做的,不过确实偏板子,所以被 识破了。本道题就不给代码了(因为没有意义,发了也看不懂)
寻找题目位置
题解
这个题目应该不难,第一个问题就是 向上取整,第二个问题就是 %
标程
int n;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
cout << n / 100 + 1 << " " << (n % 100) + 1;
return 0;
}
寻找lzp
题解
应该也不难,但是使用了最低计分可能卡掉了一些学生。
做法就是先找到 ,然后沿着 个方向找到 确定了方向后,沿着这个方向看看有没有 就行了。记得在寻找过程中数组下标是否越界。
标程
int dx[8] = {0, 0, 1, 1, 1, -1, -1, -1};
int dy[8] = {1, -1, 1, 0, -1, 1, 0, -1};
int n, ans;
char mapp[30][30];
int ok(int x, int y, int fx)
{
int xx = x + dx[fx];
int yy = y + dy[fx];
if(xx >= 1 && xx <= n && yy >= 1 && yy <= n)
{
if(mapp[xx][yy] == 'p')
{
return 1;
}
}
return 0;
}
int check(int x, int y)
{
int res = 0;
for(int i = 0; i < 8; i++)
{
int xx = x + dx[i];
int yy = y + dy[i];
if(xx >= 1 && xx <= n && yy >= 1 && yy <= n)
{
if(mapp[xx][yy] == 'z')
{
res += ok(xx, yy, i);
}
}
}
return res;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
cin >> mapp[i][j];
}
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(mapp[i][j] == 'l')
{
ans += check(i, j);
}
}
}
cout << ans << '\n';
return 0;
}
数数几个P
题解
这个只是一个单纯的大模拟,没对的同学我只能归结为懒+模拟能力有待提升。
模拟思路就是先找那个矩形,然后四个方向看看有没有竖着的就行了。
题目中给了很多的数据,自己编一些例子也并不难,很容易测出代码哪里出了问题。
标程
#include <bits/stdc++.h>
using namespace std;
int n;
char a[30][30];
bool f(int x,int y,int lenx,int leny){
int tx=x+lenx-1,ty=y+leny-1;
int cnt=0;//.的数目
int lx=100,ly=100,rx=0,ry=0;
for(int i=x;i<=tx;i++){
for(int j=y;j<=ty;j++){
if(i==x||j==y||i==tx||j==ty){
if(a[i][j]!='*') return false;
}else{
if(a[i][j]=='.'){
cnt++;
lx=min(lx,i);
ly=min(ly,j);
rx=max(rx,i);
ry=max(ry,j);
}
}
}
}
if(cnt!=(rx-lx+1)*(ry-ly+1)){
return false;
}
return true;
}
bool check(int x,int y,int lenx,int leny){
int tx=x+lenx-1,ty=y+leny-1;
//tx ty lenx leny
//上行旗杆
if(a[x-1][y]=='*'){
for(int i=x;i<=tx;i++) if(a[i][y-1]=='*'||a[i][ty+1]=='*') return false; //左右列
for(int i=y;i<=ty;i++) if(a[tx+1][i]=='*') return false;//下行
//矩形 四边 sx,fx, sy,fy
int sx=x-1,fx=x-1,sy=y,fy=y;
while(a[sx-1][y]=='*') sx--;
while(a[x-1][sy-1]=='*') sy--;
while(a[x-1][fy+1]=='*') fy++;
if(sy<y&&fy>ty) return false;
if(fy-sy+1<=leny) return false;
for(int i=sx;i<=fx;i++){
for(int j=sy;j<=fy;j++){
if(i==sx&&a[i-1][j]=='*') return false;
if(i==fx&&(j<y||j>ty)&&a[i+1][j]=='*') return false;
if(j==sy&&a[i][j-1]=='*') return false;
if(j==fy&&a[i][j+1]=='*') return false;
if(a[i][j]!='*') return false;
}
}
return true;
}
//下行旗杆
if(a[tx+1][y]=='*'){
for(int i=x;i<=tx;i++) if(a[i][y-1]=='*'||a[i][ty+1]=='*') return false; //左右列
for(int i=y;i<=ty;i++) if(a[x-1][i]=='*') return false;//上行
//矩形 四边 sx,fx, sy,fy
int sx=tx+1,fx=tx+1,sy=y,fy=y;
while(a[fx+1][y]=='*') fx++;
while(a[tx+1][sy-1]=='*') sy--;
while(a[tx+1][fy+1]=='*') fy++;
if(sy<y&&fy>ty) return false;
if(fy-sy+1<=leny) return false;
for(int i=sx;i<=fx;i++){
for(int j=sy;j<=fy;j++){
if(i==sx&&(j<y||j>ty)&&a[i-1][j]=='*') return false;
if(i==fx&&a[i+1][j]=='*') return false;
if(j==sy&&a[i][j-1]=='*') return false;
if(j==fy&&a[i][j+1]=='*') return false;
if(a[i][j]!='*') return false;
}
}
return true;
}
//左行旗杆
if(a[x][y-1]=='*'){
for(int i=x;i<=tx;i++) if(a[i][ty+1]=='*') return false; //右列
for(int i=y;i<=ty;i++) if(a[x-1][i]=='*'||a[tx+1][i]=='*') return false;//上下行
//矩形 四边 sx,fx, sy,fy
int sx=x,fx=x,sy=y-1,fy=y-1;
while(a[sx-1][y-1]=='*') sx--;
while(a[fx+1][y-1]=='*') fx++;
while(a[x][sy-1]=='*') sy--;
if(sx<x&&fx>tx) return false;
if(fx-sx+1<=lenx) return false;
for(int i=sx;i<=fx;i++){
for(int j=sy;j<=fy;j++){
if(i==sx&&a[i-1][j]=='*') return false;
if(i==fx&&a[i+1][j]=='*') return false;
if(j==sy&&a[i][j-1]=='*') return false;
if(j==fy&&(i<x||i>tx)&&a[i][j+1]=='*') return false;
if(a[i][j]!='*') return false;
}
}
return true;
}
//右行旗杆
if(a[x][ty+1]=='*'){
for(int i=x;i<=tx;i++) if(a[i][y-1]=='*') return false; //左列
for(int i=y;i<=ty;i++) if(a[x-1][i]=='*'||a[tx+1][i]=='*') return false;//上下行
//矩形 四边 sx,fx, sy,fy
int sx=x,fx=x,sy=ty+1,fy=ty+1;
while(a[sx-1][ty+1]=='*') sx--;
while(a[fx+1][ty+1]=='*') fx++;
while(a[x][fy+1]=='*') fy++;
if(sx<x&&fx>tx) return false;
if(fx-sx+1<=lenx) return false;
for(int i=sx;i<=fx;i++){
for(int j=sy;j<=fy;j++){
if(i==sx&&a[i-1][j]=='*') return false;
if(i==fx&&a[i+1][j]=='*') return false;
if(j==sy&&(i<x||i>tx)&&a[i][j-1]=='*') return false;
if(j==fy&&a[i][j+1]=='*') return false;
if(a[i][j]!='*') return false;
}
}
return true;
}
return false;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
}
}
// cout<<f(1,2,3,4);
int c=0;
for(int i=1;i<n;i++){
for(int j=1;j<n;j++){
for(int lenx=3;i+lenx-1<=n;lenx++){
for(int leny=3;j+leny-1<=n;leny++){
if(f(i,j,lenx,leny)){
if(check(i,j,lenx,leny)){
//cout<<i<<" "<<j<<" "<<lenx<<" "<<leny<<endl;
c++;
}
}
}
}
}
}
cout<<c;
}
TooYoung的诅咒2.0
题解
首先,随机移动的意思是:
对于任意一个点而言,若以它为起点的边有 个( 为 则不会继续移动),那么这x条边每条边被移动到的概率都是(这个点被移动到个概率 )。
对于任意一个点而言,它的被移动到的概率是所有以它为终点的边被移动到的概率的和。
因为是一个有向无环图,所以可以参考拓扑排序的入度思想。
拓扑排序可以为我们提供一个完全有序的 的搜索方式。
起点的被移动到的概率是 。
之后可以缩图使入度为 的点只有起点之后再按拓扑序遍历,也可以直接按照拓扑序遍历。
遍历时注意,深度为 的点即使有以它为起点的边也是不能继续移动的。
最后遍历一遍所有点,将深度为 的点的被移动到的概率加和,就是所求的概率。
标程
int n, m, s, deep[maxn], ru[maxn], cnt[maxn];
vector<int>G[maxn];
double ans[maxn], ANS;
queue<int>q;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m >> s;
for(int i = 1; i <= n; i++)
cin >> deep[i];
for(int i = 1; i <= m; i++)
{
int x, y;
cin >> x >> y;
if(deep[x] == 0) continue;
G[x].push_back(y);
cnt[x]++;
ru[y]++;
}
for(int i = 1; i <= n; i++)
{
if(ru[i] == 0 && i != s)
{
q.push(i);
}
}
while(q.empty() == 0)
{
int now = q.front(); q.pop();
int siz = (int)G[now].size();
for(int i = 0 ; i < siz; i++)
{
int nxt = G[now][i];
ru[nxt]--;
if(ru[nxt] == 0 && nxt != s)
q.push(nxt);
}
}
q.push(s);
ans[s] = 10000;
while(q.empty() == 0)
{
int now = q.front(); q.pop();
int siz = (int)G[now].size();
for(int i = 0 ; i < siz; i++)
{
int nxt = G[now][i];
ans[nxt] += ans[now] / cnt[now];
ru[nxt]--;
if(ru[nxt] == 0) q.push(nxt);
}
}
for(int i = 1; i <= n; i++)
{
if(deep[i] == 0) ANS += ans[i];
}
if(ANS >= 5000) cout << "YES\n";
else cout << "NO\n";
return 0;
}
趣味二维数组
题解
这个就是前面所说的第 题,学过二分图的同学不难发现,这显然是一个二分图问题,那么二分答案再二分图判断一下就行了。