【河南省第十三届ICPC】A\F\I\J\L\M

A-祝融传火

题意:

找到一个位置满足条件:A[x][y],A[x+H-1][y],A[x][y+W-1],A[x+H-1][y+W-1]均存在且相等

分析:

签到题,直接遍历,注意不要越界。

代码:

#include <bits/stdc++.h>
using namespace std;
#define mod 10e9+7
int a[1005][1005];
int h,w;
int n,m;
bool is(int i,int j){
    if(i>=1&&i<=n&&j>=1&&j<=m)return 1;
    else return 0;
}
bool kk(int x,int y,int v){
   if(is(x+h-1,y)&&a[x+h-1][y]==v)
   if(is(x,y+w-1)&&a[x][y+w-1]==v)
   if(is(x+h-1,y+w-1)&&a[x+h-1][y+w-1]==v)
    return 1;
   return 0;

}
int main(){
   cin>>n>>m;
   for(int i=1;i<=n;i++)
   for(int j=1;j<=m;j++){
    cin>>a[i][j];
   }
   cin>>h>>w;
   int flag=0;
   for(int i=1;i<=n;i++)
   for(int j=1;j<=m;j++){
    if(kk(i,j,a[i][j])){flag=1;}
   }
   if(flag)cout<<"YES"<<endl;
   else cout<<"NO"<<endl;
return 0;
}

F-图像识别

题意:

找到#的坐标。

分析:

签到题。判断找到原点,再让#和原点相减。

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e3+7;
char a[maxn][maxn];
int n,m;
bool yes(int i,int j){
	int f0=0;
	if(i+1>=n||(i+1<n&&a[i+1][j]=='*'))
	   f0++;
	if(i-1<0||(i-1>=0&&a[i-1][j]=='*'))
		f0++;
	if(j+1>=m||(j+1<m&&a[i][j+1]=='*'))
		f0++;
	if(j-1<0||(j-1>=0&&a[i][j-1]=='*'))
		f0++;
		if(f0==4) return 1;
	return 0;
}
int main() {
	int i0,j0,i1,j1;
	cin>>n>>m;
	int f=0;
	for(int i=0;i<n;i++)
	  for(int j=0;j<m;j++)
	     {
		 cin>>a[i][j];
		 if(a[i][j]=='#') {	i0=i,j0=j; }
	     } 
	for(int i=0;i<n;i++)
	  for(int j=0;j<m;j++)
	    if(a[i][j]=='*'&&yes(i,j)) 
		{i1=i,j1=j;break; }
	cout<<j0-j1<<' '<<i1-i0<<endl;
	  
	return 0;
}

I-七便士

题意:

七便士谜题是一个古老的谜题,其规则如下:
• 方盘上有八个圆坑,每个圆坑能正好放置一枚便士,每个圆坑与其他另外两个圆坑相连(图中黑线);
• 每次操作分为两部分:(每次操作两部分缺一不可)
1)将一枚便士放置于一个尚未放置便士的圆坑中;
2)再将该便士沿着黑线移动至另一尚未放置便士的圆坑中;
• 目标为成功放置七枚便士;
在这里插入图片描述

分析:

数据不大,直接暴力深搜,记录情况是否满足。
哎,我是深搜还是不熟。

#include <bits/stdc++.h>
using namespace std;
#define mod 10e9+7
#define ll long long
int a[10];
int now=0;
int ans=0;
void dfs()
{
    for(int i=1; i<=8; i++)
    {
        if(a[i]==0)
        {
            //a[i]=1;
            if(a[(i+2)%8+1]==0)
            {
                now++;
                a[i]=1;
                if(now==7)
                {
                    ans=1;
                    return ;
                }
                dfs();
                if(now==7) return ;
                a[i]=0;
                now--;
            }
            if(a[(i+4)%8+1]==0)
            {
                now++;
                a[i]=1;
                if(now==7)
                {
                    ans=1;
                    return ;
                }
                dfs();
                if(now==7) return ;
                a[i]=0;
                now--;
            }

        }
    }
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        memset(a,0,sizeof(a));
        now=0;ans=0;
        string s;
        cin>>s;
        for(int i=0; i<s.size(); i++)
        {
            int x=s[i]-'0';
            if(x)now++;
            a[i+1]=x;
        }

        if(now==7){ cout<<"Yes"<<endl;}
            else
            {
                dfs();
                if(ans)cout<<"Yes"<<endl;
                else cout<<"No"<<endl;
            }
    }
    return 0;
}

J-甜甜圈

题意:

两叠甜甜圈,可以把任意一叠位于顶端的一个甜甜圈移动到另一叠顶端。每次只能去掉最大的,看多少步能去掉完。

分析:

把两叠和在一起,像这样:
在这里插入图片描述
那么每次移动的步数就是两个最大值之间有多少个还未消的甜甜圈
那么我们可以给所有的甜甜圈标记为1,每次吃掉一个甜甜圈就标记为0,查询区间和就是它本次的移动步数
单点修改(1->0)区间查询,本题用树状数组就够啦。
整理下来就是:记录下初始位置,按照价值从大到小排序。然后从大到小求两甜甜圈的距离就好了。
注意
1)初始位置到第一个最大值之间要额外处理
2)对吃掉甜甜圈的修改

代码:

#include <bits/stdc++.h>
using namespace std;
#define mod 10e9+7
#define ll long long
const int maxn=1e5+3;
//int a[maxn];
ll C[maxn];
ll MAX=0;
struct one{
   int v,p;
}a[maxn];
bool cmp(one x ,one y){
    return x.v>y.v;
}
int lowbit(int x)
{
    return x &(-x);
}
void add(int x,int v)   //单点更新
{
    while (x < MAX)
    {
        C[x] += v;
        x += lowbit(x);
    }
}
int getsum(int x)  //区间查询
{
    int res = 0;
    while (x > 0)
    {
        res += C[x];
        x -= lowbit(x);
    }
    return res;
}

int main()
{
    int n1,n2;cin>>n1>>n2;MAX=n1+n2+1;
    for(int i=n1;i>0;i--){scanf("%d",&a[i].v);a[i].p=i;add(i,1);}
    for(int i=n1+1;i<=n1+n2;i++){scanf("%d",&a[i].v);a[i].p=i;add(i,1);}
    sort(a+1,a+n1+n2+1,cmp);
    //for(int i=1;i<=n1+n2;i++)cout<<a[i].p<<endl;
    ll ans=min(abs(n1-a[1].p),abs(n1+1-a[1].p));//初始位置到第一个最大值的距离
    for(int i=1;i<n1+n2;i++){
        ans+=(abs(getsum(a[i].p)-getsum(a[i+1].p))-1);//每次步数
        add(a[i].p,-1);//让被吃掉的甜甜圈的影响消失。
    }
    printf("%lld",ans);
    return 0;
}

L-手动计算

题意:

求两椭圆的面积并

分析:

给的数据非常小,精确度也非常底…直接撒点数符合题意的位置的数目。1600*1600,大概1e6,放心做。
或者推数学公式。。。数学大佬可以推推,我就算了。。。

代码:

#include <bits/stdc++.h>
using namespace std;
#define mod 10e9+7
int main(){
   int  t;cin>>t;
   while(t--){
        double a,b,c,d;cin>>a>>b>>c>>d;
        int ans=0;
    for(double i=-8;i<=8;i+=0.01)
    for(double j=-8;j<=8;j+=0.01){
        double s1=i*i/(a*a)+j*j/(b*b);
        double s2=i*i/(c*c)+j*j/(d*d);
        if(s1<=1||s2<=1)ans++;
    }
    printf("%.1f\n",(double)ans/10000);
   }
return 0;
}

M-输入输出

题意:

求染色代价。具体看题目吧。

分析:

。。。。给了非常多没用的变量迷惑,看着非常唬人,但其实是本场最签到的题。

代码:

#include <bits/stdc++.h>
using namespace std;
#define mod 10e9+7
#define ll long long

int main()
{
    int n,m,k;cin>>n>>m>>k;
    ll ans=0;
    while(m--){
        int l,r;cin>>l>>r;
        ans+=abs(l-r);
    }
    int x;
    for(int i=0;i<k;i++)cin>>x;
    cout<<ans<<endl;
    return 0;
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值