codeforces893 A-D

893A:

题意:A,B,C再玩国际象棋 他们的代号是(1,2,3)。A,B必须先玩,输的人下场换人。他们记录了n场比赛记录,第i个数代表第i局赢的人。让你检查这个日志的正确性。

思路:简单模拟。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int vis[4]={0,1,1,0};
    int n,m;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>m;
        if(vis[m]==0) {cout<<"NO"<<endl;return 0;}
        else{
            for(int j=1;j<=3;j++)
            {
                if(j==m)continue;
                vis[j]==1?vis[j]=0:vis[j]=1;
            }
        }
    }
    cout<<"YES"<<endl;
    return 0;
}

893B:

题意:给你一个数,让你找这个数的所有除数中,最大的”特殊的数“。 特殊的数定义为:k=(2^k - 1) * (2*k - 1). 数据范围是n (1 ≤ n ≤ 10^5)

思路:根据公式打个表,暴力找就好了。

#include <bits/stdc++.h>
using namespace std;//100000
int a[8]={1,6,28,120,496,2016,8128,32640};
int poww(int a,int b)
{
    int ans=1,base=a;
    while(b!=0){
        if(b&1!=0)
        ans*=base;
        base*=base;
        b>>=1;
    }
   return ans;
}
int main()
{
    int n;
    int ma=-1;
    scanf("%d",&n);
    int sq=sqrt(n);
    for(int i=1;i<=sq;i++)
    {
        if(n%i!=0)continue;
        else
        {
            int temp1=i;
            int temp2=n/i;
            for(int j=0;j<8;j++)
            {
                if(temp1==a[j] || temp2==a[j])
                ma=max(ma,a[j]);
            }
        }
    }
    printf("%d\n",ma);
    return 0;
}


893C:

题意:你有一个信息要让所有人知道,所有人都有一个贿赂的价格,并告诉你谁和谁是朋友。如果你贿赂其中一个人,他会把这个消息告诉他的朋友,朋友又会告诉朋友的朋友,问你最小花费。

思路:数据规模挺友好的,简单并查集,注意long long就好,。

#include <bits/stdc++.h>
typedef long long ll;
ll f[100005];
ll find(ll a)
{
    if(f[a]==a) return f[a];
    else
        f[a]=find(f[a]);
        return f[a];
}
int main()
{
    ll c[100005];
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%lld",&c[i]),f[i]=i;
    for(int i=1;i<=m;i++)
    {
        ll a,b,t1,t2;
        scanf("%lld%lld",&a,&b);
        t1=find(a);
        t2=find(b);
        if(t1==t2)continue;
        else{
          (c[t1]<c[t2])?f[t2]=f[t1]:f[t1]=f[t2];
        }

    }
    for(int i=1;i<=n;i++){find(f[i]);}
    ll sum=0;
    for(int i=1;i<=n;i++)
    {
        if(f[i]!=i)continue;
        else {sum+=c[i];}
    }
    printf("%lld\n",sum);
    return 0;
}
893D:

题意:有一张信用卡,d代表这张卡里最多存款上限。有n个数,第i个数代表第i天的进出账情况,如果是0他就要检查卡里的钱,如果小于0,他就要去还钱把欠的还上,也能多存,但不能超过存储上限。在有解的情况下,问你最少去银行的次数,当然如果某一天进账数使卡里的钱大于d了,则输出-1。

思路:设当前账户的最小值和最大值。当最小值大于d的时候输出-1,检测的时候最大值<0的时候,就要存钱了

#include <bits/stdc++.h>
using namespace std;
struct _st{
    int min;
    int max;
}c;
int main()
{
    int n,d,ans=0;
    scanf("%d%d",&n,&d);
    c.min=0,c.max=0;
    int a;
    for(int i=1;i<=n;i++){
        scanf("%d",&a);
        if(a)
        {
            c.min+=a,c.max+=a;
            if(c.min>d) {printf("-1");return 0;}
            if(c.max>d) c.max=d;
        }else{
            if(c.min<0) c.min=0;
            if(c.max<0){c.max=d,ans++;}
        }
    }
    printf("%d\n",ans);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CodeForces - 749C Voting 是一道有趣的计数题,它的题意是给定了两个候选人 A 和 B 的得票情况,票数相等的情况下,我们需要按照一定的规则进行投票,直到最后一个候选人胜出。具体来说,如果当前的票数相等,我们需要按照轮流投票的规则,每次投给 A 或者 B,直到最后一个候选人胜出。如果某一时刻 A 的票数比 B 多 2 票以上,那么 A 就直接胜出,同样的,如果 B 的票数比 A 多 2 票以上,那么 B 就直接胜出。 我们可以用两个变量 sa 和 sb 来表示 A 和 B 的票数,然后依次遍历每一个投票者的选择。如果当前 A 和 B 的票数相等,我们就按照轮流投票的规则,每次投给 A 或者 B,直到最后一个候选人胜出。如果 A 和 B 的票数相差 2 票以上,那么直接输出胜出者的名字。最后一定会有一个候选人胜出,因为在每一轮投票之后,A 和 B 的票数都会有所增加,最终一定会有一个候选人胜出。 下面是该问题的 Java 代码实现: ``` import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); String s = sc.next(); int sa = 0, sb = 0, pa = 0, pb = 0; boolean[] sign = new boolean[n]; for (int i = 0; i < n; i++) { if (s.charAt(i) == 'D') sa++; else sb++; } while (sa > 0 && sb > 0) { for (int i = 0; i < n; i++) { if (sign[i]) continue; if (s.charAt(i) == 'D') { if (pb > 0) { pb--; sa--; sign[i] = true; } else pa++; } else { if (pa > 0) { pa--; sb--; sign[i] = true; } else pb++; } if (sa == 0 || sb == 0) break; } } if (sa == 0) System.out.println("R"); else System.out.println("D"); } } ``` 该代码的时间复杂度为 $O(n)$,空间复杂度为 $O(n)$,其中 n 表示投票者的数量。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值