第11周

教育场64

A.Inscribed Figures
题意:给三角形 圆和正方形,求组合的图形的点数。

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define mod 1000000007
#define INF MAX_INT/2
using namespace std;
int a[105];
int main(void)
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    int ans=0,temp=0;;
    for(int i=2;i<=n;i++){
        if((a[i-1]==1&&a[i]==2)||(a[i-1]==2&&a[i]==1))
            ans+=3;
        if((a[i-1]==1&&a[i]==3)||(a[i-1]==3&&a[i]==1))
            ans+=4;
        if((a[i-1]==3&&a[i]==2)||(a[i-1]==2&&a[i]==3)){
            temp=1;
            break;
        }
    }
    if(!temp) for(int i=3;i<=n;i++){
        if(a[i]==2&&a[i-1]==1&&a[i-2]==3) ans--;
    }
    if(temp) cout<<"Infinite";
    else cout<<"Finite\n"<<ans;
    return 0;
}

B.Ugly Pairs
将给定的字符串改为前后不相邻的字符串

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define mod 1000000007
#define INF MAX_INT/2
using namespace std;
int a[30];
int main(void)
{
    int t=1;cin>>t;
    string s;
    while(t--){
        memset(a,0,sizeof a);
        string a1,a2;
        a1=a2="";
        cin>>s;
        for(int i=0;i<s.length();i++){
            a[s[i]-'a']++;
        }
        for(int i=1;i<26;i+=2){
            while(a[i]--) a1+=('a'+i);
        }
        for(int i=0;i<26;i+=2){
            while(a[i]--) a2+=('a'+i);
        }
        if(abs(a2[0]-a1[a1.length()-1])!=1) cout<<a1<<a2<<endl;
        else if(abs(a1[0]-a2[a2.length()-1])!=1) cout<<a2<<a1<<endl;
        else cout<<"No answer"<<endl;
    }
    return 0;
}

C.Match Points
找两个点,其相差的数小于Z,从中间劈开,就可以防止指针没必要的错误

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define mod 1000000007
#define INF MAX_INT/2
using namespace std;
int a[200005];
int main(void)
{
    int n,z;
    cin>>n>>z;
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    sort(a,a+n);
    int l=n/2-1,ans=0;
    for(int i=n-1;i>=n/2;i--){
        while(l>=0){
            if(a[i]-a[l--]>=z){
                ans++;
                break;
            }
        }
    }
    cout<<ans;
    return 0;
}

D.0-1-Tree
思路:就是找爸爸。然后答案还是有点迷。

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define mod 1000000007
#define INF MAX_INT/2
#define maxx 200005
using namespace std;
struct node
{
    int fa[maxx],num[maxx];
    //fa[] 这个东西的爸爸是谁,father嘛,num记录有连接的多少个数了
    int find(int x){//找爸爸
        if(fa[x]==x) return x;//自己是自己的就是爸爸
        else return fa[x]=find(fa[x]);
        //自己不是自己的就找到不是自己的数的爸爸,然后认它做爸爸
    }
}no[2];
int main(void)
{
    int n;cin>>n;
    for(int i=1;i<=n;i++){//初始化,每个人都是自己的爸爸,然后自己的数目为1
        no[0].fa[i]=i,no[0].num[i]=1;
        no[1].fa[i]=i,no[1].num[i]=1;
    }
    int x,y,z;
    for(int i=1;i<n;i++){
        cin>>x>>y>>z;
        x=no[z].find(x),y=no[z].find(y);//找到自己的爸爸
        if(x!=y){//爸爸不一样
            no[z].fa[x]=y;//x认y为爸爸
            no[z].num[y]+=no[z].num[x];//并且把x的num值给y的加上
        }
    }
    ll ans=0;
    for(int i=1;i<=n;i++){
        ans+=(ll)no[0].num[no[0].find(i)] * no[1].num[no[1].find(i)] -1;
        //为什么要减1,x!=y嘛,自己和自己配对的那条路得减掉
//1上的点到1上的点,0到0上的点,0到1上的点
    }
    cout<<ans;
    return 0;
}

E. Special Segments of Permutation
题意: 给一个1 ~ n的排列,求出有多少个区间满足a[l] + a[r] = max(a[l] ~ a[r])。
思路: 枚举最大值,然后对于每个最大值,把其左边暂时符合条件的区间左端点存入 set 集合里,然后枚举该最大值右边符合条件的数,如果集合里存在该最大值减去该值的差,则答案加1。(盗用同僚的思路嘿嘿)

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define mod 1000000007
#define inf 0x3f3f3f3f
#define maxx 200005
using namespace std;
int a[200005];
int main(void)
{
    int n;cin>>n;
    int ans=0;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=2;i<n;i++){
        if(a[i-1]>a[i]||a[i]<a[i+1]) continue;
        set<int> s;
        for(int j=i-1;j>=1&&a[j]<a[i];j--) s.insert(a[j]);
        for(int j=i+1;j<=n&&a[j]<a[i];j++)
            if(s.count(a[i]-a[j])) ans++;
    }
    cout<<ans;
    return 0;
}

教育场70

A.You Are Given Two Binary Strings…
将y的最后一个1和x的那个位置的前面一个1对其就可以了

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define mod 1000000007
#define INF MAX_INT/2
using namespace std;
int a[30];
int main(void)
{
    int t;cin>>t;
    string x,y;
    while(t--){
        cin>>x>>y;
        x=" "+x;
        y=" "+y;
        int i,k=0;
        for(i=y.length();i>=0;){
            if(y[i]=='1') break;
            i--;
            k++;
        }
        int ans=0;
        for(int j=x.length()-k;j>=0;){
            if(x[j]=='1') break;
            j--;
            ans++;
        }
        cout<<ans<<endl;
    }
    return 0;
}

B. You Are Given a Decimal String…
假设你有一个特殊的x-y计数器。该计数器可以存储一些十进制数值;首先,计数器的值为0。
计数器执行以下算法:它打印其最低位,然后在其值中添加x或y。因此,此计数器生成的所有序列都从0开始。例如,4-2计数器可以如下操作:
1.打印0,并将其值加4,所以当前值为4,输出为0;
2.打印4,并将其值加4,所以当前值为8,输出为04;
3.打印8,并将其值加4,所以当前值为12,输出为048;
4.打印2,并将其值加2,所以当前值为14,输出为0482;
5.它打印4,并将其值加4,因此当前值为18,输出为04824。
这只是可能的产出之一;例如,如果我们选择在每个步骤中添加2,则同一计数器可以生成0246802468024作为输出。
您从其中一个x-y计数器中记下了打印序列。但是序列被破坏了,序列中的几个元素可以被删除。
现在您想要恢复丢失的数据,但您甚至不知道您使用的计数器的类型。你有一个十进制字符串s - 序列的剩余数据。
对于所有0≤x,y <10,计算必须在字符串s中插入的最小位数,以使其成为x-y计数器的可能输出。请注意,您不能更改字符串s中的数字顺序或删除其中的任何数字;仅允许插入。

思路:求出从某值到某值所需要的次数,并且求出最小次数储存起来。

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define mod 1000000007
#define inf 0x3f3f3f3f
#define maxx 200005
using namespace std;
int a[10][10];
string s;
int fun(int x,int y)
{
    memset(a,inf,sizeof a);
    for(int i=0;i<=9;i++){
        a[i][(i+x)%10]=a[i][(i+y)%10]=1;//从i到i+x和i+y能够一步到达
    }
    for(int k=0;k<=9;k++){
        for(int i=0;i<=9;i++){
            for(int j=0;j<=9;j++){
                a[i][j]=min(a[i][j],a[i][k]+a[k][j]);//找最短路
            }
        }
    }
    int l=s.length();
    int ans=0;
    for(int i=0;i<l-1;i++){
        if(a[s[i]-'0'][s[i+1]-'0']==inf) return -1;
        else ans+=a[s[i]-'0'][s[i+1]-'0']-1 ;  //因为是统计缺失是数字,所以要减1
    }
    return ans;
}
int main(void)
{
    cin>>s;
    for(int i=0;i<10;i++){
        for(int j=0;j<10;j++){
            cout<<fun(i,j)<<" ";
        }
        cout<<endl;
    }
    return 0;
}

D.Print a 1337-string…
子序列是可以通过删除某些元素而不改变其余元素的顺序从另一个序列派生的序列。
给你一个整数n。
您必须找到一个由数字{1,3,7}组成的序列s,使其具有完全n个子序列等于1337。
例如,序列337133377有6个子序列等于1337:
3371–33–3–77– (you can remove the second and fifth characters);
3371–3–33–77– (you can remove the third and fifth characters);
3371–3–3–377– (you can remove the fourth and fifth characters);
3371–33–3–7–7 (you can remove the second and sixth characters);
3371–3–33–7–7 (you can remove the third and sixth characters);
3371–3–3–37–7 (you can remove the fourth and sixth characters).
请注意,序列s的长度不得超过10e5。
逆过来,将答案转化为问题,只输出一个。
找出最小的3的个数,可此时m*(m-1)不一定等于n,那么就将m–,然后剩下的用一插在后面俩个三的前面单独提供答案就可以了,形式:133333333…111111…337。

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define mod 1000000007
#define inf 0x3f3f3f3f
#define maxx 200005
using namespace std;

int main(void)
{
    int t;cin>>t;
    while(t--){
        int n;cin>>n;
        string ans="1";
        ll m=0;
        while(m*(m-1)/2<=n) m++;
        m--;
        for(int i=0;i<m-2;i++) ans+="3";
        for(int i=0;i<(n-m*(m-1)/2);i++) ans+="1";
        cout<<ans+"337"<<endl;
    }
    return 0;
}

自闭的周六训练,早上自闭,下午全小组自闭。
刷了好几道杭电的题,牛客也去翻了一下。学的好杂啊啊啊啊啊

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值