match2(双周赛)

第二次双周赛

2-1 输出全排列

题目描述

在这里插入图片描述
在这里插入1图片描述

思路分析

标准的板子题,DFS+数组记录即可。

#include<bits/stdc++.h>
using namespace std;
int n;
int vis[15];
int a[15];
void dfs(int num){
    if (num==n){
        for (int i=1; i<=n; i++)
            cout<<a[i];
        cout<<endl;
        return;
    }
    for (int i=1; i<=n; i++){
        if (!vis[i]){
            a[num+1]=i;
            vis[i]=1;
            dfs(num+1);
            vis[i]=0;
        }
    }
}
int main(){
    cin>>n;
    for (int i=1; i<=n; i++){
        vis[i]=1;
        a[1]=i;
        dfs(1);
        vis[i]=0;
    }
    //system("pause");
    return 0;   
}

注意:
a[num+1]=i;不可写成a[++num]=i;
比赛卡死在这个地方很久,再一次喜提T1用时倒数

2-2 山

题目描述

请添加图片描述
请添加图片描述

思路分析

可以用DFS,如果当前的点没有被扫描过,就说明这是一个新的山峰,并且以此为一个起点,去拓展出整个山峰,将这个点相邻的点均打下标记,即vis[i]=1


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

const int maxn=2e3+5;
int n,m;
int num=0;
int a[maxn][maxn];
int vis[maxn][maxn];
int d1[4]={-1,0,0,1};
int d2[4]={0,-1,1,0};
struct node{
    int x;
    int y;
};
queue <node> q;
void dfs(int x,int y){

    if (vis[x][y])
        return;

    if (a[x][y] && !vis[x][y]){
        q.push(node{x,y});
        num++;
        vis[x][y]=num;
        while (!q.empty()){
            int nx=q.front().x;
            int ny=q.front().y;
            q.pop();
            for (int i=0; i<4; i++){
                int tx=nx+d1[i];
                int ty=ny+d2[i];

                if (tx>=1 && tx<=n && ty>=1 && ty<=m && a[tx][ty] && !vis[tx][ty]){
                    q.push(node{tx,ty});
                    vis[tx][ty]=num;
                }
            }
        }
    }
}
int main(){
    int sx,sy;
    cin>>n>>m;
    for (int i=1; i<=n; i++)
        for (int j=1; j<=m; j++){
            cin>>a[i][j];
            }
    for (int i=1;  i<=n; i++)
        for (int j=1; j<=m; j++){
            dfs(i,j);
        }
    cout<<num;
    return 0;   
}

2-3 跳跃

题目描述

请添加图片描述

请添加图片描述

解题思路

这道题很类似 P1135 奇怪的电梯 其实肯定是祝神CV来的
这道题更简化了,甚至不需要输出最小步数,所以DFSBFS时间复杂度理论上差不多了。
然而,在你连续WA了几发后,在你DFSBFS各写了一遍都不对后,在你经过了题目怀疑、数据怀疑、自我怀疑、人生怀疑后,就会很轻松 地发现,原来下标是从0开始的!!!(认真读数据范围)

#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+5;
int a[maxn];
int st,n;
int vis[maxn];
bool jud=0;
void dfs(int x){

    if (jud){
        return;
    }
    int step=a[x];

    if (!step){
        jud=1;
        return;
    }

    int to1=x-step;
    int to2=x+step;
    if (to1>=0 && to1<n && !vis[to1]){
        vis[to1]=1;
        dfs(to1);
    }
    if (to2<n && to2>1 && !vis[to2]){
        vis[to2]=1;
        dfs(to2);
    }
}
int main(){
    cin>>n;
    for (int i=0; i<n; i++)
        cin>>a[i];
    cin>>st;
    vis[st]=1;
    dfs(st);
    if (jud){
        cout<<"True";
    }
    else 
        cout<<"False";
    //system("pause");
    return 0;   
}

2-4 回文数文回

题目描述

请添加图片描述

解题思路

思路一:枚举前五位数字
由回文数的特征可知,九位回文数只需知道前五位即可确定,所以只需枚举前五位数字即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e9+5;
const int st=1e8;
int main(){
    int n;
    int num=0;
    cin>>n;
    string s;
    s=to_string(n);
    int a,b,c,d;
    a=s[0]-'0';
    b=s[1]-'0';
    c=s[2]-'0';
    d=s[3]-'0';
    for (int a1=1; a1<=a; a1++)
        for (int b1=0; b1<=9; b1++)
            for (int c1=0; c1<=9; c1++)
                for (int d1=0; d1<=9; d1++)
                    for (int e1=0; e1<=9; e1++){
                        int k=a1*100000000+b1*10000000+c1*1000000+d1*100000+e1*10000+d1*1000+c1*100+b1*10+a1;
                        if (k<=n){
                            num++;
                        }
                    }
    cout<<num;
    return 0;   
}

思路2:打表
最大1e9,打表即可。可以找一个合适的间隔,保证每次只需算间隔内的数即可。注意这个间隔不能太大,太大会超时;也不能太小,间隔过于密集会导致代码长度超过限制16KB。我找了1e6的间隔。

#include<bits/stdc++.h>
using namespace std;
const int section_num=1e4+5;
const int maxn=1e9+5;
const int st=1e8;
int a[section_num]={0,100,200,300,400,500,600,700,800,900,1000,1100,1200,1300,1400,1500,1600,1700,1800,1900,2000,2100,2200,2300,2400,2500,2600,2700,2800,2900,3000,3100,3200,3300,3400,3500,3600,3700,3800,3900,4000,4100,4200,4300,4400,4500,4600,4700,4800,4900,5000,5100,5200,5300,5400,5500,5600,5700,5800,5900,6000,6100,6200,6300,6400,6500,6600,6700,6800,6900,7000,7100,7200,7300,7400,7500,7600,7700,7800,7900,8000,8100,8200,8300,8400,8500,8600,8700,8800,8900,9000,9100,9200,9300,9400,9500,9600,9700,9800,9900,10000,10100,10200,10300,10400,10500,10600,10700,10800,10900,11000,11100,11200,11300,11400,11500,11600,11700,11800,11900,12000,12100,12200,12300,12400,12500,12600,12700,12800,12900,13000,13100,13200,13300,13400,13500,13600,13700,13800,13900,14000,14100,14200,14300,14400,14500,14600,14700,14800,14900,15000,15100,15200,15300,15400,15500,15600,15700,15800,15900,16000,16100,16200,16300,16400,16500,16600,16700,16800,16900,17000,17100,17200,17300,17400,17500,17600,17700,17800,17900,18000,18100,18200,18300,18400,18500,18600,18700,18800,18900,19000,19100,19200,19300,19400,19500,19600,19700,19800,19900,20000,20100,20200,20300,20400,20500,20600,20700,20800,20900,21000,21100,21200,21300,21400,21500,21600,21700,21800,21900,22000,22100,22200,22300,22400,22500,22600,22700,22800,22900,23000,23100,23200,23300,23400,23500,23600,23700,23800,23900,24000,24100,24200,24300,24400,24500,24600,24700,24800,24900,25000,25100,25200,25300,25400,25500,25600,25700,25800,25900,26000,26100,26200,26300,26400,26500,26600,26700,26800,26900,27000,27100,27200,27300,27400,27500,27600,27700,27800,27900,28000,28100,28200,28300,28400,28500,28600,28700,28800,28900,29000,29100,29200,29300,29400,29500,29600,29700,29800,29900,30000,30100,30200,30300,30400,30500,30600,30700,30800,30900,31000,31100,31200,31300,31400,31500,31600,31700,31800,31900,32000,32100,32200,32300,32400,32500,32600,32700,32800,32900,33000,33100,33200,33300,33400,33500,33600,33700,33800,33900,34000,34100,34200,34300,34400,34500,34600,34700,34800,34900,35000,35100,35200,35300,35400,35500,35600,35700,35800,35900,36000,36100,36200,36300,36400,36500,36600,36700,36800,36900,37000,37100,37200,37300,37400,37500,37600,37700,37800,37900,38000,38100,38200,38300,38400,38500,38600,38700,38800,38900,39000,39100,39200,39300,39400,39500,39600,39700,39800,39900,40000,40100,40200,40300,40400,40500,40600,40700,40800,40900,41000,41100,41200,41300,41400,41500,41600,41700,41800,41900,42000,42100,42200,42300,42400,42500,42600,42700,42800,42900,43000,43100,43200,43300,43400,43500,43600,43700,43800,43900,44000,44100,44200,44300,44400,44500,44600,44700,44800,44900,45000,45100,45200,45300,45400,45500,45600,45700,45800,45900,46000,46100,46200,46300,46400,46500,46600,46700,46800,46900,47000,47100,47200,47300,47400,47500,47600,47700,47800,47900,48000,48100,48200,48300,48400,48500,48600,48700,48800,48900,49000,49100,49200,49300,49400,49500,49600,49700,49800,49900,50000,50100,50200,50300,50400,50500,50600,50700,50800,50900,51000,51100,51200,51300,51400,51500,51600,51700,51800,51900,52000,52100,52200,52300,52400,52500,52600,52700,52800,52900,53000,53100,53200,53300,53400,53500,53600,53700,53800,53900,54000,54100,54200,54300,54400,54500,54600,54700,54800,54900,55000,55100,55200,55300,55400,55500,55600,55700,55800,55900,56000,56100,56200,56300,56400,56500,56600,56700,56800,56900,57000,57100,57200,57300,57400,57500,57600,57700,57800,57900,58000,58100,58200,58300,58400,58500,58600,58700,58800,58900,59000,59100,59200,59300,59400,59500,59600,59700,59800,59900,60000,60100,60200,60300,60400,60500,60600,60700,60800,60900,61000,61100,61200,61300,61400,61500,61600,61700,61800,61900,62000,62100,62200,62300,62400,62500,62600,62700,62800,62900,63000,63100,63200,63300,63400,63500,63600,63700,63800,63900,64000,64100,64200,64300,64400,64500,64600,64700,64800,64900,65000,65100,65200,65300,65400,65500,65600,65700,65800,65900,66000,66100,66200,66300,66400,66500,66600,66700,66800,66900,67000,67100,67200,67300,67400,67500,67600,67700,67800,67900,68000,68100,68200,68300,68400,68500,68600,68700,68800,68900,69000,69100,69200,69300,69400,69500,69600,69700,69800,69900,70000,70100,70200,70300,70400,70500,70600,70700,70800,70900,71000,71100,71200,71300,71400,71500,71600,71700,71800,71900,72000,72100,72200,72300,72400,72500,72600,72700,72800,72900,73000,73100,73200,73300,73400,73500,73600,73700,73800,73900,74000,74100,74200,74300,74400,74500,74600,74700,74800,74900,75000,75100,75200,75300,75400,75500,75600,75700,75800,75900,76000,76100,76200,76300,76400,76500,76600,76700,76800,76900,77000,77100,77200,77300,77400,77500,77600,77700,77800,77900,78000,78100,78200,78300,78400,78500,78600,78700,78800,78900,79000,79100,79200,79300,79400,79500,79600,79700,79800,79900,80000,80100,80200,80300,80400,80500,80600,80700,80800,80900,81000,81100,81200,81300,81400,81500,81600,81700,81800,81900,82000,82100,82200,82300,82400,82500,82600,82700,82800,82900,83000,83100,83200,83300,83400,83500,83600,83700,83800,83900,84000,84100,84200,84300,84400,84500,84600,84700,84800,84900,85000,85100,85200,85300,85400,85500,85600,85700,85800,85900,86000,86100,86200,86300,86400,86500,86600,86700,86800,86900,87000,87100,87200,87300,87400,87500,87600,87700,87800,87900,88000,88100,88200,88300,88400,88500,88600,88700,88800,88900,89000,89100,89200,89300,89400,89500,89600,89700,89800,89900,100000};
int main(){
    int n;
    int num=0;
    cin>>n;
    num+=a[(n-st)/1000000];
    for (int i=st+(n-st)/1000000*1000000+1; i<=n; i++)
        {
            string s;
            s=to_string(i);
            bool jud=0;
            for (int i=0,j=8; i<4; i++,j--){
                if (s[i]!=s[j]){
                    jud=1;
                    break;
                }
            }
            if (!jud){
                num++;
            }
        }
    cout<<num;
    //system("pause");
    return 0;   
}

2-5 最长光路

题目描述

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

思路分析

DFS分析四个方向即可,需要用到三维数组vis来记录这个方向上是否拜访过。如果一个地方并且其对应的方向被拜访了两次,就说明这是一个环。
ps:题目貌似只说明了如果光源朝各个方向摆设,最终光线都会射向盒子外部,那么小明认为经过格子最多的光路是最酷的,但是没说明射不出盒子外部时的情况下,最酷的也是格子最多的。看了测试数据才明白的QAQ

#include <bits/stdc++.h>
using namespace std;
const int maxn=500+5;
int n,m;
char c[maxn][maxn];
int sx,sy;
int d1[4]={-1,0,1,0};
int d2[4]={0,1,0,-1};
int d3[4]={0,1,2,3};
int vis[maxn][maxn][4];
int ans=0,preans=0;
bool jud=0;
void dfs(int x,int y,int d,int num){

    if (jud){
        return;
    }

    int dx=x;
    int dy=y;
    while (1){
        dx=dx+d1[d];
        dy=dy+d2[d];
        num++;

        if (!(dx>=1 && dx<=n && dy>=1 && dy<=m)){
            ans=max(ans,num);
            return;
        }


        if (vis[dx][dy][d]){
            ans=-1;
            jud=1;
            return;
        }

        if (c[dx][dy]=='\\'){
            int td;
            switch (d){
                case 0:td=3;break;
                case 1:td=2;break;
                case 2:td=1;break;
                case 3:td=0;break;
            }
            if (vis[dx][dy][td]){
                ans=-1;
                jud=1;
                return;
            }
                vis[dx][dy][td]=1;
                dfs(dx,dy,td,num);
                vis[dx][dy][td]=0;
        
            return;
        }

        if (c[dx][dy]=='/'){
            int td;
            switch (d){
                case 0:td=1;break;
                case 1:td=0;break;
                case 2:td=3;break;
                case 3:td=2;break;
            }
            if (vis[dx][dy][td]){
                ans=-1;
                jud=1;
                return;
            }
                vis[dx][dy][td]=1;
                dfs(dx,dy,td,num);
                vis[dx][dy][td]=0;
            
            return;
        }

        if (c[dx][dy]=='C'){
            ans=max(ans,num);
            return;
        }

        if (c[dx][dy]=='.'){
            continue;
        }
    }
}
int main(){
    cin>>n>>m;
    for (int i=1; i<=n; i++)
        for (int j=1; j<=m; j++)
            cin>>c[i][j];
    cin>>sx>>sy;
    int maxd=-1;
    for (int i=0; i<4; i++){
        vis[sx][sy][i]=1;
        dfs(sx,sy,i,0);
        vis[sx][sy][i]=0;
        if (ans!=preans){
            maxd=i;
        }
        if (ans==-1){
            break;
        }
        preans=ans;
    }

    switch (maxd){
        case 0:cout<<"U"<<endl; break;
        case 1:cout<<"R"<<endl; break;
        case 2:cout<<"D"<<endl; break;
        case 3:cout<<"L"<<endl; break;
    }
    if (ans==-1){
        cout<<"COOL";
    }
    else 
        cout<<ans;    
    //system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值