ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2022寒假集训day6

2022-01-27 15:31:12  阅读:157  来源: 互联网

标签:10 00 && day6 sum int 寒假 2022 ans


day6

上午还是做四道题

T1

区域
【上机练习】
1、编程计算由“*”号围成的下列图形的面积。面积计算方法是统计*号所围成的闭合曲线
中水平线和垂直线交点的数目。如下图所示,在 10*10 的二维数组中,有“*”围住了 15
个点,因此面积为 15。

【样例输入】area.in
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 0 0 0
0 0 0 0 1 0 0 1 0 0
0 0 0 0 0 1 0 0 1 0
0 0 1 0 0 0 1 0 1 0
0 1 0 1 0 1 0 0 1 0
0 1 0 0 1 1 0 1 1 0
0 0 1 0 0 0 0 1 0 0
0 0 0 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0
【样例输出】area.out
15

#include <bits/stdc++.h>
using namespace std;
int a[12][12];
int main()
{
    int sum=0;
    for(int i=0;i<12;i++)
        for(int j=0;j<12;j++)
            a[i][j]=0;
    for(int i=0;i<12;i++)
    {
            a[i][0]=-1;
            a[0][i]=-1;
            a[i][11]=-1;
            a[11][i]=-1;
    }
    for(int i=1;i<11;i++)
        for(int j=1;j<11;j++)
        {
            cin>>a[i][j];
        }
     
    for(int i=1;i<11;i++)
        for(int j=1;j<11;j++)
        {
            if(a[i][j]==0&&a[i-1][j]==-1)
                a[i][j]=-1;
            if(a[i][j]==0&&a[i][j-1]==-1)
                a[i][j]=-1;
            if(a[i][j]==0&&a[i+1][j]==-1)
                a[i][j]=-1;
            if(a[i][j]==0&&a[i][j+1]==-1)
                a[i][j]=-1;               
        }
    for(int j=1;j<11;j++)
        for(int i=1;i<11;i++)
        {
            if(a[i][j]==0&&a[i-1][j]==-1)
                a[i][j]=-1;
            if(a[i][j]==0&&a[i][j-1]==-1)
                a[i][j]=-1;
            if(a[i][j]==0&&a[i+1][j]==-1)
                a[i][j]=-1;
            if(a[i][j]==0&&a[i][j+1]==-1)
                a[i][j]=-1;               
        }   
    for(int i=1;i<11;i++)
        for(int j=1;j<11;j++)
        {
            if(a[i][j]==0)
            sum++;
        }
    cout<<sum;        
}

 整道题给人一种看的很明白,但是没有思路写;

关键在我这道题没用搜索还做了出来(doge

————————————————————————————————————————

T2

奇怪的电梯 洛谷P1135

2、奇怪的电梯(lift)
【问题描述】
大楼的每一层楼都可以停电梯,而且第 i 层楼(1<=i<=N)上有一个数字 Ki(0<=Ki<=N)。
电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果
不能满足要求,相应的按钮就会失灵。例如:3 3 1 2 5 代表了 Ki(K1=3,K2=3,......),从一
楼开始。在一楼,按“上”可以到 4 楼,按“下”是不起作用的,因为没有-2 楼。那么,
从 A 楼到 B 楼至少要按几次按钮呢?
【输入格式】
输入文件共有二行,第一行为三个用空格隔开的正整数,表示 N,A,B(1≤N≤200, 1 ≤
A,B≤N),第二行为 N 个用空格隔开的正整数,表示 Ki。
【输出格式】
输出文件仅一行,即最少按键次数,若无法到达,则输出-1

 

#include<bits/stdc++.h>
using namespace std;

int n,A,B,cnt=10001;
int k[210];
bool b[210]={0}; 
int d[2]={1,-1};

void dfs(int x,int s)
{
    if(x==B) cnt=min(s,cnt); 
    if(s>cnt) return;
     
    for(int i=0;i<2;i++){
        int X=x+d[i]*k[x];
        if(X>=1 && X<= n && b[X]){
            s++;
            b[x]=false;
                        dfs(X,s);
            b[x]=true;
            s--;
        }
     }      
}

int main(){
    cin>>n>>A>>B;
    
    memset(b,true,sizeof(b));
    for(int i=1;i<=n;i++) cin>>k[i];
    
    b[A]=false;
    if(A==B) cnt=0;
    else dfs(A,0);
    if(cnt==10001) cout<<-1;
    else cout<<cnt;
    return 0;
} 

反复提交了好几次才发现少了memset(b,true,sizeof(b));
一直二十分。整体来说还是标准的深搜。

————————————————————————————————————————

T3

产生数    洛谷P1037

题目描述

给出一个整数 nnn(n<1030n \lt 10^{30}n<1030)和 kkk 个变换规则(k≤15k \le 15k≤15)。

规则:

  • 一位数可变换成另一个一位数。
  • 规则的右部不能为零。

例如:n=234n=234n=234。有规则(k=2k=2k=2):

  • 222->555
  • 333->666

上面的整数 234234234 经过变换后可能产生出的整数为(包括原数):

  • 234234234
  • 534534534
  • 264264264
  • 564564564

共 444 种不同的产生数。

现在给出一个整数 nnn 和 kkk 个规则。求出经过任意次的变换(000次或多次),能产生出多少个不同整数。

仅要求输出个数。

输入格式

第一行两个整数 n,kn,kn,k。

接下来 kkk 行,每行两个整数 xi,yix_i,y_ixi​,yi​。

输出格式

输出能生成的数字个数。

 

#include<iostream>
using namespace std;
string n;
int k,can[10][10];
int ans[500]={1};
int l=1,b[10];

void dfs(int x)
{
    for(int i=0;i<l;i++)
        ans[i]*=x;
    for(int i=0;i<l;i++)
        if(ans[i]>=10)
        {
            ans[i+1]+=ans[i]/10;
            ans[i]%=10;
        }
    while(ans[l]>0)
    {
        ans[l+1]=ans[l]/10;
        ans[l]=ans[l]%10;
        l++;
    }
}
int main()
{
    cin>>n>>k;
    int x,y;
    while(k--)
    {
        cin>>x>>y;
        can[x][y]=1;
    }
    for(int v=0;v<10;v++)
        for(int j=0;j<10;j++)
            for(int i=0; i<10; i++)
                if(i!=j&&j!=v&&i!=v)
                    if(can[i][v]==1&&can[v][j]==1) can[i][j]=1;
    
    int len=n.length();
    for(int i=0; i<len; i++)
    {
        int n1=n[i]-'0',change=1;
        for(int j=0;j<10;j++)
        if(can[n1][j]==1&&n1!=j)
            change++;
        b[n1]=change;
    }
    for(int i=0;i<len;i++) dfs(b[n[i]-'0']);
    for(int i=l-1;i>=0;i--) cout<<ans[i];
    return 0;
}

颇为麻烦的一道题

第一眼上去以为会有规律,结果自己找了几个数据自己算,发现竟然是递推(bushi)。就写个提交,洛谷给我20分,竟然骗到了。

言归正传,首先搜索规则中可以变换的情况,还要用10来取模,如果发现得出的数与之前的相同,不能sum++了

————————————————————————————————————————

T4

家庭问题

【问题描述】
有 n 个人,编号为 1,2,......n,另外还知道存在 K 个关系。一个关系的表达为二元组(α,
β)形式,表示α,β为同一家庭的成员。
当 n,k 和 k 个关系给出之后,求出其中共有多少个家庭、最大的家庭中有多少人?
例如:n=6,k=3,三个关系为(1,2),(1,3),(4,5)
此时,6 个人组成三个家庭,即:{1,2,3}为一个家庭,{4,5}为一个家庭,{6}单独为
一个家庭,第一个家庭的人数为最多。

【输入格式】
文件的第一行为 n,k 二个整数(1≤n≤100)(用空格分隔)
接下来的 k 行,每行二个整数(用空格分隔)表示关系
【输出格式】
二个整数(分别表示家庭个数和最大家庭人数)

 

#include <bits/stdc++.h>
using namespace std;
int n,k;
int a,b;
int p[120],sum[120];
int search(int x){
    if(p[x]!=x) p[x]=search(p[x]);
    return p[x];
}
int main(){
    cin>>n>>k;
    int family=n;
    int number=1;
    for(int i=1;i<=n;i++){
        p[i]=1;
        p[i]++;
        sum[i]=1;
    }
    while(k--){
        cin>>a>>b;
        a=search(a),b=search(b);
        if(a!=b){
            p[a]=b;
            sum[b]+=sum[a];
            family--;
            number=max(number,sum[b]);
        } 
            
    }
    cout<<family<<" "<<number;
    return 0;
}

很正经的搜索回溯啦,

对家庭数和人数进行初始化,如果发现输入中重复出现的元素,说明二者可以算到一起(也就是合为一家)

计数也就减少一个,人数++。

 

标签:10,00,&&,day6,sum,int,寒假,2022,ans
来源: https://www.cnblogs.com/su-yichen/p/15850023.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有