记一次灰常失败的打cf经历,暴露了自己的许多问题,以及自己逻辑能力和代码能力不是很强
A题:http://codeforces.com/contest/1066/problem/A
这道水题上来,想暴力遍历,不可能,但是那个(L,R],处理的不好,这个逻辑没搞好,导致12分才a。。。。其实左开就是为了取上界,(R / v ) - (L + v - 1) / v + 1;
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const double PI = acos(-1);
const double eps = 1e-8;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int N = 1e5 + 5;
int main()
{
int t;
cin >> t;
while(t--)
{
LL L,v,l,r;
cin >> L >> v >> l >> r;
LL k = L / v;
LL p = (r / v) - ((l + v - 1) / v) + 1;
//cout << k << " " << p << endl;
cout << k - p << endl;
}
return 0;
}
B题:http://codeforces.com/contest/1066/problem/B
其实这道题思路很清晰,但是我就是对这种类似两点移动的这种代码就很烦,那个地方没写好就是一堆bug或者是wa,以后要多做这种题的训练,不能嫌烦,敲定做法后先构造一遍代码思路再敲,要不然会敲很长时间,右边界没处理好,一直wa。。。。大的教训啊,希望自己以后逻辑思维能强点
代码写的比较丑,其实先判定是否输出-1,直接暴力vis标记就行,但是当时思维就是不对劲。。。
还想边滑动会判断-1的情况,写了两个版本,都删掉了,特别困难。。。还是先把-1的情况过滤掉吧
右边界的话,如果出现某个点的右边界大于n,那么就可以输出了,否则可能会多判
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const double PI = acos(-1);
const double eps = 1e-8;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int N = 1005;
int a[N][2];
int main()
{
int n,r;
int k = 0;
scanf("%d %d",&n,&r);
for(int i = 1;i <= n;++i){
int x;
scanf("%d",&x);
if(x == 1){
a[k][0] = i - r + 1;
a[k++][1] = i + r - 1;
}
}
for(int i = 0;i < k;++i){
if(i == 0){
if(a[i][0] > 1){
printf("-1\n");
return 0;
}
}else{
if(a[i][0] - a[i - 1][1] > 1){
printf("-1\n");
return 0;
}
}
}
if(a[k - 1][1] < n){
printf("-1\n");
return 0;
}
int p = 1;
int pre = 1;
int cnt = 0;
for(int i = 0;i < k;++i){
if(a[i][0] <= p){
pre = a[i][1] + 1;
}else{
cnt++;
p = pre;
if(p > n){
printf("%d\n",cnt);
return 0;
}
i--;
}
}
if(pre > n){
cnt++;
printf("%d\n",cnt);
}
return 0;
}
C题:http://codeforces.com/contest/1066/problem/C
赛后补的题,这道题直接上来用双端队列,查询用find函数,必定超时。。。。。
然后怎么办呢,其实两点法(为什么想不到呢),设一个左边界,一个右边界,查询应该是O(1)查询,所以需要一个pos数组存一下它的放的位置。。。。把起始位置设为300000。。。。。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const double PI = acos(-1);
const double eps = 1e-8;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int N = 3 * 1e5;
int pos[200005];
int main()
{
int q;
scanf("%d",&q);
char ch;int x;
int l = 300000,r = 300000;
scanf(" %c %d",&ch,&x);
pos[x] = l;
for(int i = 1;i < q;++i){
scanf(" %c %d",&ch,&x);
if(ch == 'L'){
l--;pos[x] = l;
}else if(ch == 'R'){
r++,pos[x] = r;
}else{
int tmp = pos[x];
printf("%d\n",min(tmp - l,r - tmp));
}
}
return 0;
}
D题:http://codeforces.com/contest/1066/problem/D
我觉得这道题的最大值有点迷惑人,弄的题意和自己理解的有点偏差,按他给的程序那样走的话,因为物品必须都遍历完,所以直接倒着装物品,因为最后的物品是一定被装在盒子里的
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const double PI = acos(-1);
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int N = 2 * 1e5 + 5;
int a[N];
int main()
{
int n,m,k;
scanf("%d %d %d",&n,&m,&k);
for(int i = 1;i <= n;++i){
scanf("%d",&a[i]);
}
int cnt = n;
while(m--)
{
int sum = 0;
while(cnt >= 1 && sum + a[cnt] <= k){
sum += a[cnt--];
}
}
printf("%d\n",n - cnt);
return 0;
}
E题:http://codeforces.com/contest/1066/problem/E
这道题显然比前面三题简单点,赛后也是马上就有想法,马上打出来的
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const double PI = acos(-1);
const double eps = 1e-8;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int N = 2 * 1e5 + 5;
const LL mod = 998244353;
char s1[N];
char s2[N];
LL b[N];
LL pow_mod(LL n,LL m)
{
LL x = n;
LL sum = 1;
while(m){
if(m & 1) sum = sum * x % mod;
m >>= 1;
x = x * x % mod;
}
return sum;
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
scanf("%s",s1);
scanf("%s",s2);
for(int i = 0;i < m;++i){
b[i] = s2[i] - '0';
}
for(int i = 1;i < m;++i){
b[i] += b[i - 1];
}
int k = m - 1;
int MIN = min(n,m);
int len = n;
LL sum = 0;
for(int i = len - 1;i >= len - MIN;--i,--k){
if(s1[i] == '1'){
sum = (sum + b[k] * pow_mod(2LL,len - 1 - i) % mod) % mod;
//cout << sum << endl;
}
//cout << pow_mod(2LL,len - 1 - i) << endl;
}
printf("%lld\n",sum);
return 0;
}