想说一下昨晚的cf吧
A
t组样例,n * m 要求黑格(周围至少有一个白格)比白格(周围至少有一个黑格)多一个
最笨的就是想跟着题意走,把所有的格一分为二(巴拉巴拉) 似乎也不太好实现
实际上让第一个格为白色 其他的为黑色 本题OK 了
B
t组样例,n数据个数,接下来两行分别是ab数组 其中a数组只包含-1,0,1,当i < j的时候,aj = aj + ai;(可以进行无数次)
判断b能不能由a通过这种操作得到
先说一下我的思路:
如果第一个数不相等,直接输出no;
否则从最后一个数开始判断,最开始用mp记录每个数以及出现的次数,
当到这个数的时候,先把这个数从map中出现的次数-1,然后再看bi和ai的差值,如果是0,不用看了,负数的话,看看-1存在不,正数的话,看看1存在不,不存在的话输出no,存在的话继续往下走
今天看了别人写的,发现我想的太复杂了,读入a数组的同时 ,找l,r分别记录1和-1第一次出现的位置
读入b数组的同时,判断b数组的这一项和a数组这一项的关系,
如果b数组> a数组这项 ,说明a要从前面的项找1,即判断l的位置,如果l 不存在或者l >= i 说明不符合,flag = 0;
如果小于 说明a要从前面的项找-1,即判断l的位置,如果r不存在或者r>= i 说明不符合,flag = 0;
最后判断flag 就行了
cin>>n; int l=0,r=0,u=1; for(int i=1;i<=n;i++){ cin>>a[i]; if(a[i]==1&&!l)l=i; if(a[i]==-1&&!r)r=i; } for(int i=1;i<=n;i++){ cin>>b[i]; if(b[i]>a[i]&&(l>=i||!l))u=0; if(b[i]<a[i]&&(r>=i||!r))u=0; } if(flag)cout<<"YES "; else cout<<"NO ";
c题
数组可以从开头或者结尾删除任意个,也可以不删,得到子序列
子序列的和不为0的个数
当时思考的时候有一个小debug
样例二
3
41 -41 41
得到
41
41 -41(两个数和为0,不符合)
41 -41 41(因为41 -41不符合,所以这一项也不符合)
-41
-41 41(两个数和为0,不符合)
41
所以输出是3
从第一个数开始找,如果前缀和为0,从第二个数开始找,直到前缀和为0,再从第三个,一直到最后一个
把每次找的段数累加
我的 TLE了
#include <bits/stdc++.h> using namespace std; #define int long long const int maxn = 2e5 + 10; int n; int a[maxn],sum[maxn]; int ans; signed main(){ //freopen("in","r",stdin); ios::sync_with_stdio(0); cin >> n; for(int i = 1; i <= n; i++) { cin >> a[i]; if(a[i]) ans++; sum[i] = sum[i - 1] + a[i]; } int l = 1,r = 2; while(1){ if(l == n) break; while(sum[r] - sum[l - 1]){ r++; ans++; if(r == n + 1) { break; } } l++; r = l + 1; } cout << ans << endl; return 0; }
#include <bits/stdc++.h> using namespace std; #define ll long long ll n, x, s, ans,l; map<ll, ll> mp; int main() { freopen("in", "r", stdin); ios::sync_with_stdio(0); cin >> n; mp[0] = 0; for (int i = 1; i <= n; i++) { cin >> x; s += x; if (mp.find(s) != mp.end()) l = max(l, mp[s] + 1); ans += i - l; mp[s] = i; } cout << ans; return 0; }
昨天才感觉自己的acm入门