codeforces div4 859

前言:自己还是个弱鸡,代码多少有点丑陋,还请各位大神赐教

  1. A.签到题,无需多言。直接上代码了。

#include<iostream>
#include<string>
#include<algorithm>
#include<set>
#include<vector>
#include<utility>      
#include<map>
#include<queue>
#include<climits>
#include<cstring>
#include<cmath>
#include<unordered_set>
using namespace std;
typedef long long ll;
const int N =2e5+10;
int n;
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int a,b,c;scanf("%d%d%d",&a,&b,&c);
        cout<<(a+b==c?'+':'-')<<'\n';
    }
    return 0;
}
  1. B. Grab the Candies

题意:观察给出的长度为n的数组里奇数之和和偶数之和分别为多少,最后如果奇数和大于偶数和,则输出“YES”,否则输出“NO”;所以直接上代码吧。

#include<iostream>
#include<string>
#include<algorithm>
#include<set>
#include<vector>
#include<utility>      
#include<map>
#include<queue>
#include<climits>
#include<cstring>
#include<cmath>
#include<unordered_set>
using namespace std;
typedef long long ll;
const int N =2e5+10;
int n;
int arr[N];
void solve(){
    memset(arr,0,sizeof(arr));
    int n;cin>>n;int cnt1=0,cnt2=0;
    for(int i=1;i<=n;i++){
        cin>>arr[i];
        if(arr[i]&1)cnt2+=arr[i];
        else cnt1+=arr[i];}
    cout<<(cnt1>cnt2?"YES":"NO")<<'\n';
}
int main(){
    int T;
    cin>>T;
    while(T--){
    solve();
    }
    return 0;
}
  1. C. Find and Replace

题意:给出一个长度为n的字符串,用0或1去将字符串里的所有字符都代替掉,问是否能组成相邻元素不相同的数字字符串。

例:abacababa,

将a用1代替字符串变为1b1c1b1b1;

将b用0代替字符串变为101c10101;

将c用0代替字符串变为101010101;

则能组成相邻元素不相同的数字字符串,输出"YES";

题解:观察题中所给出的样例,咱不难发现,相同字符之间的字符个数如果是奇数,则能行,如果是偶数则不行,所以将第一次出现的字符标记一下,并将它所处的位置也记录下来,等待下一次的相同字符出现,判断一下即可。所以还是上代码吧!

#include<algorithm>
#include<set>
#include<vector>
#include<utility>      
#include<map>
#include<queue>
#include<climits>
#include<cstring>
#include<cmath>
#include<string>
#include<unordered_set>
#include<iostream>
using namespace std;
typedef long long ll;
const int N = 30;
string s;
int n;
int t[N];
void sovle() {
    memset(t,-1,sizeof(t));
    cin>>n>>s;
    for(int i=0;i<s.size();i++){
        int tt=s[i]-'a';
        if(t[tt]==-1){t[tt]=i;}
        else if((i-t[tt])&1){cout<<"NO"<<'\n';return ;}
    }cout<<"YES"<<'\n';
}

int main() {
    int T;
    cin >> T;
    while (T--) {
        sovle();
    }
    return 0;
}
  1. D. Odd Queries

题意:首先给出一个长度为n的整数数组,请求做q次的询问,每次询问给定一个[ L , R ]的范围,在给定一个k值,要求咱将整数数组中在范围里的数都换成k值,然后计算数组之和是否为奇数,如果是则输出”YES“,反正则输出”NO“;

题解:前缀加差分;

关键点:如何将原数组中的元素替换为题中给出的元素并计算其和;

其实很简单的,首先记录一个前缀和的数组sum,每次询问时先用原数组之和加上给出的范围的元素个数*k值,也就是sum[n]+=(R-L+1)*k;再将原数组中这个范围的和减掉,也就是sum[n]-=(sum[R]-sum[L-1]),最后判断是是否为奇数;这里的sum[n]代码中用ans代替了,保证原数组之和的不变;

(注意题中给出数据较大,如果用cin或者cout请取消同步,否则代码容易超时,(1996s)偷笑,嘻嘻);

#include<iostream>
#include<string>
#include<algorithm>
#include<set>
#include<vector>
#include<utility>      
#include<map>
#include<queue>
#include<climits>
#include<cstring>
#include<cmath>
#include<unordered_set>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
ll n,q;
ll arr[N];
ll sum[N];
void solve() {
    ll ans = 0;
    scanf("%lld%lld", &n, &q);
    memset(arr, 0, sizeof(arr));
    memset(sum, 0, sizeof(sum));
    for (int i = 1; i <= n; i++) {
        scanf("%lld",&arr[i]); sum[i] = sum[i - 1] + arr[i];
    }
    while (q--) {
        ans = sum[n];
        ll l, r, k; scanf("%lld%lld%lld", &l, &r, &k);
        ans += (r - l + 1) * k;
        ans -= (sum[r] - sum[l - 1]);
        if (ans & 1)printf("YES\n");
        else printf("NO\n");
    }
}
int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        solve();
    }
    return 0;
}
  1. E题不太会,以后再补吧(主要烦躁了,比赛时就没看太懂)。

  1. F题比赛的时候没时间了,还是自己太弱弱了。其实就是一道模拟题,不断地模拟,注意结束的条件就好。(俺也是赛后抄了某位佬的码,好烦躁,实在不想再去想了)

题意:还是不说了吧,直接上代码了。

#include<algorithm>
#include<set>
#include<vector>
#include<utility>      
#include<map>
#include<queue>
#include<climits>
#include<cstring>
#include<cmath>
#include<string>
#include<unordered_set>
#include<iostream>
using namespace std;
typedef long long ll;
const int N = 30;
string s;
int n,m,i,j,ii,jj,x,y;
int num,cnt,ff;
int d[5][2]={0,0,1,1,1,-1,-1,1,-1,-1};        //控制方向
void check(int x,int y,int t){
    if(x==n&&y==m){if(t!=4)num++;ff=4;return ;}   
    if(x==1&&y==1){if(t!=1)num++;ff=1;return ;}
    if(x==n&&y==1){if(t!=3)num++;ff=3;return ;}
    if(x==1&&y==m){if(t!=2)num++;ff=2;return ;}

    if(y==1&&t==4){num++;ff=3;return ;}
    if(y==1&&t==2){num++;ff=1;return ;}
    if(y==m&&t==1){num++;ff=2;return ;}
    if(y==m&&t==3){num++;ff=4;return ;}
    
    if(x==1&&t==3){num++;ff=1;return ;}
    if(x==1&&t==4){num++;ff=2;return ;}
    if(x==n&&t==1){num++;ff=3;return ;}
    if(x==n&&t==2){num++;ff=4;return ;}
}                                        //一麻袋的判断条件。
void sovle() {
    string s;
    int f=0;
    cin>>n>>m>>i>>j>>ii>>jj>>s;
    if(s=="DR")ff=1;
    if(s=="DL")ff=2;
    if(s=="UR")ff=3;
    if(s=="UL")ff=4;
    num=0,cnt=0;
    x=i,y=j;
    while(1){
        if(x==ii&&y==jj){f=1;break;}
        if(x==i&&y==j)cnt++;         //防止进入死循环
        if(cnt>=5)break;
        check(x,y,ff);               //撞墙后改变方向
        x+=d[ff][0];                    
        y+=d[ff][1];
    }
    if(f)cout<<num<<'\n';
    else cout<<-1<<'\n';
}

int main() {
    int T;
    cin >> T;
    while (T--) {
        sovle();
    }
    return 0;
}

  1. G1. Subsequence Addition (Easy Version)

题意:给你个长度为n数组的数组,判断它是否能通过题中所给方式不断地插入数来组成。

题解:先给数组排个序,然后直接判断数组一开始有多少个1,用cnt计数,然后再从数组中不是1的位置开始判断,如果此位置上的数小于等于cnt,则它能被组成,并将它加在cnt里,(此时可能有很多和我一样的菜菜可能一下子没想明白,下面是简单的证明过程)

如果有数组a={1,1,2,3,4,5,6},

则首先cnt=2;不是1的位置为pos=3(后面位置就用pos代替了,数组的位置也是1~n,方便理解,(可能俺太踩踩了))。

则此时1到2都能被组成,然后判断pos=3位置上的数是否小于等于cnt,如果小于则能被组成。

则此时能组成的数有1,2,3(1+2),4(1+1+2),所以cnt=4;

pos=4;判断是否小于等于cnt,是则此时能组成的数为1,2,3,4,5(2+3),6(1+2+3),7(1+1+2+3);

pos=5;照旧则能被组成的数为。。。。。

想信家人们已经能理解了,理解不了的家人就再在草稿纸上花花,肯定能想通的,(其实俺上则所中想通的(嘻嘻)),所以上代码吧。

#include<iostream>
#include<string>
#include<algorithm>
#include<set>
#include<vector>
#include<utility>      
#include<map>
#include<queue>
#include<climits>
#include<cstring>
#include<cmath>
#include<unordered_set>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
ll n;
ll arr[N];
void solve() {
    memset(arr, 0, sizeof(arr));
    ll i,cnt=0;
    cin >> n;
    for (i = 1; i <= n; i++)cin >> arr[i];
    sort(arr + 1, arr + n + 1);
    for(i=1;i<=n;i++)if(arr[i]==1)cnt++;else break;
    for(;i<=n;i++)if(arr[i]<=cnt){cnt+=arr[i];continue;}
    else {cout<<"NO"<<'\n';return ;}
    cout<<"YES"<<'\n';
}
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    int T;
        cin >> T;
        while (T--) {
            solve();
        }
    return 0;
}
  1. G2. Subsequence Addition (Hard Version)

这题就不说了吧,和G1一毛一样(但得把数据开大点,就比如G1用的int这题得用long long了),cf div3或div4好像挺喜欢玩这种的,所以代码就不放了吧,和上面G1的代码一样。

总结:

还是太菜啦,但俗话说的好,一帆风顺从不是人生的常态,不断的失败才是常态。

所以如果就这样放弃,我相信在未来,每个不如意都将会有你当初选择放弃的身影。

好像有点鸡汤里,最后一句送自己吧,纪念一下自己的第一篇blog.

切勿用昨日的泪水淋湿今天的太阳,趁青春,勿虚度。

感谢阅读

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值