[蓝桥杯2020] 湖北省省赛

C题 蛇形填数

 

 答案:

761

代码:

简洁

 

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int maxn = 50;
int a[maxn][maxn];
int main(){
    int k=1;
    memset(a,0,sizeof(a));
    int cnt=1;
    while(k<=50){
         if(k%2==1){
             for(int x =k,y=1;x>=1;x--,y++){
                 a[x][y] = cnt++;
             }
         }
         else{
             for(int x=1,y=k;y>=1;x++,y--){
                 a[x][y] =cnt++;
             }
         }
         k++;
    }
    cout<<a[20][20]<<endl;
    return 0;
} 

 

E题 七段码

 

 

思路:

并查集+bfs

return :强行终止函数继续运行下去

答案:

80

代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int maxn = 25;
int map[maxn][maxn];
int ans = 0;
int visit[maxn];
int father[maxn];
void init(){
    // a b c d e f g
    // 1 2 3 4 5 6 7
    memset(map,0,sizeof(map));
    map[1][2] = map[1][6] = 1;
    map[2][7] = map[2][3] = 1;
    map[3][4] = map[3][7] = 1;
    map[4][5] = 1;
    map[5][6] = map[5][7] = 1;
    map[6][7] = 1;
}
int find(int x){//并查集路径压缩
    if(father[x]==x)
        return x;
    else{
        father[x] = find(father[x]);
        return father[x];
    }
}
void dfs(int d){
    if(d>7){
        for(int i=1;i<=7;i++)
            father[i] = i;
        for(int i=1;i<=7;i++){
            for(int j=1;j<=7;j++){
                if(visit[i]&&visit[j]&&map[i][j]){
                    int fx = find(i),fy = find(j);
                    if(fx!=fy){
                        father[fx] = fy;
                    }
                }
            }
        }
        int k=0;
        for(int i=1;i<=7;i++)
            if(visit[i]&&father[i]==i) k++;
        if(k==1) ans++;
        return ;//这里必须要 
    }
    visit[d]=1;
    dfs(d+1);
    visit[d]=0;
    dfs(d+1);
}
int main(){
    init();
    dfs(1);
    cout<<ans<<endl;
    return 0;
}

 

H 子串分值

 

 

 

 思路:

 

代码:

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn = 2e5+10;
typedef long long ll;
char a[maxn];
int id[27][maxn],nu[27],b[27];
ll ans;
int main(){
    cin>>(a+1);
    int len = strlen(a+1);
    for(int i=1;i<=len;i++){
        id[a[i]-'a'][++nu[a[i]-'a']] = i;
    }
    for(int i=1;i<=len;i++){//计算以i开头的子串的贡献 
        int top = 0;
        for(int j=0;j<=25;j++){//记录每个字母最快出现在i之后的下标 
            if(id[j][nu[j]]>=i){
                int index = lower_bound(id[j],id[j]+nu[j]+1,i)-id[j];
                b[++top] = id[j][index];
            } 
        }
        sort(b+1,b+top+1);
        int last = i;
        for(int j=2;j<=top;j++){
            ans+=(b[j]-last)*(j-1);
            last = b[j];
        }
        ans+=(len-last+1)*top;
    }
    cout<<ans<<endl;
    return 0;
}

I 平面切分

 

 

 

 

set去重

思路:

思路:

  在同一平面内,如果添加的每一条直线互不相交,则每添加一条直线,就会增加一个平面;当添加一条直线时,这条直线与当前平面内已有直线每产生一个不同位置的交点时,这条直线对平面总数量的贡献会额外增多一个,记为Si,则Si的值为经过这条直线的点+1,1为直线自身贡献的平面,结果为每一条直线的贡献加上最开始的一个平面,结果为S1到Sk的和,k为所有不重合直线的数量,再加上1.

所以我们可以在每添加一条直线时设置一个空的set,将直线与当前平面内其他直线的交点的xy坐标存入set中,如果这一条直线不是重边,则这条直线的贡献为set.size()+1,即ans为所有直线的贡献加上原来的一个平面.

时间复杂度:O(n2*log2n)

代码:

#include<iostream>
#include<stdio.h>
#include<set>
using namespace std;
typedef long long ll;
pair<double,double>p;
bool st[1010];
double s[1010][2];
ll ans;
int main(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>s[i][0]>>s[i][1];
        set<pair<double,double> >t;
        for(int j=0;j<i;j++){
            if(st[i]) continue;
            if(s[i][0]==s[j][0]){
                if(s[i][1]==s[j][1]){
                    st[i] = true; 
                    break;
                }
                else
                    continue;
            }
            p.first = (s[j][1]-s[i][1])/(s[i][0]-s[j][0]);
            p.second = (s[j][1]*s[i][0]-s[i][1]*s[j][0])/(s[i][0]-s[j][0]);
            t.insert(p);
        }
        if(!st[i]) ans+=t.size()+1;
    }
    cout<<ans+1<<endl;
    return 0;
}

 

posted @ 2020-11-09 19:09  sqsq  阅读(347)  评论(0编辑  收藏  举报