河南省第十三届ICPC大学生程序设计竞赛

A-祝融传火

暴力直接秒就行

#include<bits/stdc++.h>
using namespace std;
int A[1010][1010];
int main(){
    int n,m,a,b;
    cin>>n>>m;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            scanf("%d",&A[i][j]);
    cin>>a>>b;
    bool check=0;
    for(int i=0;i+a-1<n;i++){
        for(int j=0;j+b-1<m;j++){
            if(A[i][j]==A[i+a-1][j] && A[i+a-1][j]==A[i][j+b-1] 
               && A[i][j+b-1]==A[i+a-1][j+b-1]){
                printf("YES");check=1;break;
            }
        }
        if(check)break;
    }
    if(!check)printf("NO");
    return 0;
}

B- Honeycomb

 思路:将两个点的坐标分别求出来

1.cin,cout加速

2.图形为六边形,将其分为n层,求出每层6个端点(zs(左上)……)

!!!注意这里由于t=1e5,所以每次预处理这六个端点防超时

3.坐标:1对应(0,0)2对应(-1,-1)3对应(-2,0)……

4.对每个输入判断在哪层的哪条边上从而求坐标

5.求出坐标后,y轴上每次可以移动1,相应的x轴对应的距离减小1

//所以最后是max(0ll,abs(p1.x-p2.x)-abs(p1.y-p2.y))/2     《-------x轴方向上距离的格子数

6.记得+1

#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct _p{ ll x,y; }p1,p2;
ll zx[100010],z[100010],zs[100010],ys[100010],y[100010],yx[100010],t,a,b;;
void pre(){
    for(int n=2;n<100010;n++){
        zx[n]=3*n*n-8*n+6;//(1-n,1-n)
        z[n] =3*n*n-7*n+5;//(2-2n,0)
        zs[n]=3*n*n-6*n+4;//(1-n,n-1)
        ys[n]=3*n*n-5*n+3;//(n-1,n-1)
        y[n] =3*n*n-4*n+2;//(2n-2,0)
        yx[n]=3*n*n-3*n+1;//(n-1,1-n)
    }
}
void cal(ll r,_p & p){//求点所在的坐标
    if(r==1){ p.x=p.y=0; }
    else{
        ll n=1;//表示所在第几层
        while(yx[n]<r)n++;
        if(r<=zx[n]){
            p.x=(1-n)+(zx[n]-r)*2;
            p.y=1-n;
        }
        else if(r<=z[n]){
            p.x=(2-2*n)+(z[n]-r);
            p.y=0-(z[n]-r);
        }
        else if(r<=zs[n]){
            p.x=(1-n)-(zs[n]-r);
            p.y=(n-1)-(zs[n]-r);
        }
        else if(r<=ys[n]){
            p.x=(n-1)-2*(ys[n]-r);
            p.y=n-1;
        }
        else if(r<=y[n]){;
            p.x=(2*n-2)-(y[n]-r);
            p.y=0+(y[n]-r);
        }
        else{
            p.x=(n-1)+(yx[n]-r);
            p.y=(1-n)+(yx[n]-r);
        }  
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    pre();
    cin>>t;
    while(t--){
        cin>>a>>b;
        cal(a,p1);
        cal(b,p2);
        cout<<max(0ll,abs(p1.x-p2.x)-abs(p1.y-p2.y))/2+abs(p1.y-p2.y)+1<<'\n';
    }
    return 0;
}

L-手动计算

概率论可以秒,在一个面积为S0的面上随机投n个点,其中m个在所求面积中,则当无穷大时,S=S0*m/n   (蒙特卡洛方法)

#include<bits/stdc++.h>
using namespace std;
inline bool f(double x,double y,double a,double b){
    if(x*x*b*b+y*y*a*a<a*a*b*b)return 1;
    return 0;
}

int main(){
    int T;
    cin>>T;
    while(T--){
        double a,b,c,d,x,y;
        cin>>a>>b>>c>>d;
        int cnt=0; double S=256;
        for(int i=0;i<2000;i++){
            for(int j=0;j<2000;j++){
                x=i*0.008-8,y=j*0.008-8;
                if(f(x,y,a,b) || f(x,y,c,d))cnt++;
            }
        }
        printf("%.1lf\n",S*cnt/4e6);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值