SWPUACM第二届程序设计竞赛

Posted MangataTS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SWPUACM第二届程序设计竞赛相关的知识,希望对你有一定的参考价值。

文章目录

题目说明:

E、F、G、I是我出的
B、C、H、J是任泓润出的
A、B、K、L是杨宇出的

A.善良的杨宇

解题思路

差分,然后找连续的值大于0的最长可能,具体看代码

code

#include <bits/stdc++.h>
using namespace std;
const int N = 100005;

int a[N];

int main()

    int n;
    scanf("%d",&n);
    for(int i = 1;i <= n; ++i) 
        scanf("%d",&a[i]);
    
    for(int i = n;i >= 1; --i)
        a[i] -= a[i-1];
    int loc = 0;
    int ans = 0;
    for(int i = 1;i <= n; ++i) 
        if(a[i] > 0) 
            loc++;
        
        else 
            ans = max(ans,loc);
            loc = 1;
        
    
    ans = max(ans,loc);
    printf("%d\\n",ans);
    return 0;

B.芜湖!加速!

解题思路

因为普通搜索时,我们有时可能会用到之前所搜索到的结果,这时如果我们再次搜索就显得没有必要了(会浪费很多时间呢),所以如果我们已经记录了之前搜索的答案不就可以直接用之前的搜索答案了么

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 500;//数据并不大
const int dx[]= 0,0,1,-1;
const int dy[]= 1,-1,0,0;
int r,c,ans;
int map[maxn][maxn],step[maxn][maxn];
int dfs(int x,int y) 
    if(step[x][y]) return step[x][y];//一开始每个点的步数都应为0;如果当前这个点已知其最大步数说明之前该点已被计算过就不用再重复计算了(这不是废话么- -||);
    step[x][y]=1;//既然这是一个从未走过的点那么现在来到该点至少都会使其步数为1
    for(int i=0; i<4; i++)  //四个可行的方向
        int nx=x+dx[i],ny=y+dy[i];
        if(map[nx][ny]<map[x][y]) 
            step[x][y]=max(step[x][y],1+dfs(nx,ny));//代码核心
        
    
    return step[x][y];//返回值给上一个dfs调用

int main() 
    ios::sync_with_stdio(false);
    scanf("%d%d",&r,&c);
    //初始化处理
    for(int i=0; i<=c+1; i++)  //将边界的高度设为无限高这样就免去了判断是否超出地图限制
        map[i][0]=map[i][c+1]=1e9;
    
    for(int i=0; i<=r+1; i++) 
        map[0][i]=map[r+1][i]=1e9;
    
    //读入每个点的数据
    for(int i=1; i<=r; i++) 
        for(int j=1; j<=c; j++) 
            scanf("%d",&map[i][j]);
        
    
    for(int i=1; i<=r; i++) 
        for(int j=1; j<=c; j++) 
            ans=max(dfs(i,j),ans);//每一个点都跑一边dfs,答案取最大的就是题目要求了
        
    
    cout << ans << endl;
    return 0;


C.情人节的倍数

解题思路

很简单的,是从18位位数来考虑倍数,
选数字的规则很明确,520x520x…x为任意一个数
最小,也即搜索的情况是x从0->9即可
应对条件:数字长度18和格式,
搜索中用一个参数表示长度即可,输出中直接左对齐格式输出
注意搜不到答案的时候ans为0和长整型数据就可以解决这个题了

Code

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
ll n,ans;
void dfs(ll x,int y,int z)//x为当前数字,y为数字位数,z为将选用数字 

    if(y>18)return ;
    if(x%n==0&&x)
    
        ans=x;
        return ;
    
    if(z==3)
    
        for(int i=0;i<=9;++i)
            dfs(x*10+i,y+1,0); 
    
    else
    
        if(z==0)x=x*10+5;
        else if(z==1)x=x*10+2;
        else x=x*10+0;
        dfs(x,y+1,z+1);
    

int main()

    int t;
    scanf("%d",&t);
    while(t--)
    
        ans=0;
        scanf("%lld",&n);
        dfs(0,0,0);
        if(ans%n||ans==0)puts("5201314");
        else printf("%-18lldLOVE\\n",ans); 
        // 用%-18lld格数简单处理格式问题 
    
    return 0;
 

D.像素游戏

解题思路

S串中实际下标 0 1 2 3 4 5 6 7 8 9
每一个字母的5行对应S串中的数字序号构成一个数组 (为方便,这里公用第一个下标0用数字0占去)
模拟大法可好了,
分析每一个字母的构造建立一个通用的字符串数组S
接着用每一个字母的5行结构写一个转译数组code
得到字符串时,将 当前字母的 5个code数 对应于S字符串中 添加到 ans字符串中
最后直接每行输出ans字符串数组即可

Code

#include<bits/stdc++.h>
using namespace std;
#define N 1000
bool mp[N][N];
int code[][6]=0,1,3,9,4,4,0,6,4,6,4,6,0,7,2,2,2,7,0,6,4,4,4,6,0,9,2,9,2,9,0,9,2,9,2,2,0,5,2,8,4,5,0,4,4,9,4,4;
char S[][7]="      ","  o   ","o     "," o o  ","o   o "," ooo  ","oooo  "," oooo ","o ooo ","ooooo ";
/*
S串中实际下标 0        1        2        3        4        5        6        7        8        9
每一个字母的5行对应S串中的数字序号构成一个数组 (为方便,这里公用第一个下标0用数字0占去) 
模拟大法可好了,
分析每一个字母的构造建立一个通用的字符串数组S
接着用每一个字母的5行结构写一个转译数组code
得到字符串时,将 当前字母的 5个code数 对应于S字符串中 添加到 ans字符串中
最后直接每行输出ans字符串数组即可 
*/

char s[N];
char ans[6][100];
/*
  o  
 o o 
ooooo
o   o
o   o

oooo
o   o
oooo
o   o
oooo

 oooo
o    
o
o
 oooo

oooo
o   o
o   o
o   o
oooo

ooooo
o
ooooo
o
ooooo

ooooo
o
ooooo
o
o

 ooo
o   
o ooo
o   o
 ooo

o   o
o   o
ooooo
o   o
o   o
*/
int main()

    scanf("%s",&s);
    memset(ans,0,sizeof ans);
    for(int i=0;s[i];++i)//每个字母 
    
        for(int k=1;k<=5;++k)//5层 
        
            strcat(ans[k],S[code[s[i]-'a'][k]]);//可以不使用strcat函数写源代码,自学 
        
    
    for(int i=1;i<=5;++i)puts(ans[i]); 
    return 0;
 

E.孤独的数字(easy)

解题思路:

其实这道题比后面那个题难,是我虚晃一枪,hh

我们用map标记一下出现过的前缀和(或者叫子序列),然后一旦发现有相等的,那么必然会存在相加为0的情况,这个时候就需要插入一个数,这个数假设就去INF,反正就不让它为0,然后将map存储的前缀和信息清空,从当前位置作为第一个元素继续前缀和,注意的是,每次清空需要将map[0]标记为true

Code

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

const int N = 200005;

map<ll,bool> mp;
int a[N];

int main()

    int n;
    ll sum = 0;
    scanf("%d",&n);
    mp[0] = true;
    int ans = 0;
    for(int i = 0;i < n; ++i) 
        scanf("%d",&a[i]);
        sum += a[i];
        if(mp[sum]) 
            mp.clear();
            ans ++;
            sum = a[i];
            mp[0] = true;
        
        mp[sum] = true;
    
    printf("%d\\n",ans);
    return 0;

F.孤独的数字(hard)

解题思路

很明显我们能看出当连续的两个数之和小于十那么就需要添加一个数字,这个数字可以直接取正无穷,所以答案就是相邻的两个数之和小于十的个数

Code

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

const int N = 1000005;
int n,t;
int a[N];

int main()

    scanf("%d",&t);
    while(t--) 
        scanf("%d",&n);
        int ans = 0;
        for(int i = 0;i < n; ++i) 
            scanf("%d",&a[i]);
            if(i > 0 && a[i]+a[i-1] < 10) 
                ans++;
            
        
        printf("%d\\n",ans);
    
    return 0;

G.彩虹屁

解题思路

给大家放松的题目^^,标程是从提交AC随机抽取的

Code

#include<stdio.h>
int main()

    printf("实验室环境很好,学习氛围很浓厚,不论是acm队长还是队员都乐于助人,帮助萌新,大家互相探讨问题,研究题目时的热情都很浓烈.\\n");
    printf("这次竞赛题目灵活有趣,既照顾了新人又不失挑战性,可见出题人的良苦用心,不仅锻炼大家的思维能力又激起大家探究问题的热情.\\n");
    printf("语文不好写不出来了"); 
    return 0;

#include <iostream>
using namespace std;
int main()

    cout<<"Acm团队真的太好了,在这里不仅可以学到很多知识,还能遇到许多小伙伴,但是最重要的是可以遇见我们亲爱的谢队,真的是太好了,爱死谢队了,谢队不仅人超级好,而且代码敲的好,人也长得帅,要是我是个女生,我一定要嫁给他,啊,我对谢队的爱犹如江海一样在我心中波涌,能和谢队在一个实验室,实在是三生有幸,太好了啊谢队。同时,acm实验室真的太棒了,有热水,有空调,条件真的杠杠的,舒适安逸,是个学习的好地方,真是太高兴了能够在acm里面学习" <<endl;
    return 0;

H.无相连通图

解题思路

最短路板子题

Code

#include<bits/stdc++.h>
using namespace std; 
typedef long long ll;
#define N 100009
#define INF 0x3f3f3f3f
#define mt(x) memset(x,0,sizeof x) 
int n,m,s,dis[N],vis[N],head[N],num;
/*
图论经典 
最短路模板题
因为点数太大,就得链式向前星 
*/ 
struct iii

    int to,next,dis;
mp[N];
struct ii

    int dis,pos;
    bool operator <(const ii &x)const
    
        return x.dis<dis;
    
;
priority_queue<ii>q;
void add(int x,int y,int z)

    mp[++num].dis=z;
    mp[num].to=y;
    mp[num].next=head[x];
    head[x]=num;

void Dijkstra()

    dis[s]=0;
    q.push((ii)0,s);
    while(q.size())
    
        ii now=q.top();
        q.pop();
        int x=now.pos,y;
        if(vis[x])continue;
        vis[x]=1;
        for(int i=head[x];i;i以上是关于SWPUACM第二届程序设计竞赛的主要内容,如果未能解决你的问题,请参考以下文章

SWPUACM第二次周赛

湖南省第十二届大学生计算机程序设计竞赛 A 2016

湖南省第十二届大学生计算机程序设计竞赛Problem A 2016 找规律归类

python要求编写程序,计算得出1000以内中是3或7的倍数的所有自然数之和

SWPUACM第一届程序设计大赛

长沙学院第一届“360湖南网安基地杯”程序设计竞赛