链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5809
题目大意:区间[0, n]上,对于每一个整数[1, n],都有一个红绿灯[i - 0.5], 开始站在[0], 过一个红绿灯本身需要时间1,等红灯也需要时间1,红绿灯以1秒为间隔交替变化,给你初始状态,问
的值为多少, t(i, j)表示从点i为起点走到点j需要的时间
解题思路:今天突然想到这个题,感觉还挺有意思的。
s 1 0 1 1 0 0 1
0 -> n 1 2 3 5 6 8 9
以0为起点:1 2 3 5 6 8 9
以1为起点: 2 3 5 6 8 9
以2为起点: 1 3 4 6 7
以3为起点: 1 2 4 5
以4为起点: 2 4 5
以5为起点: 2 3
以6为起点: 1
可以观察到若该位为1,该位值则减至1,后面的值也都要减少这位减少的值,若该位为0,该位值则减至2,后面的值也都要减少这位减少的值.
(即i到n的和-第i位与1或2的差值*区间长度)
thx for https://blog.youkuaiyun.com/yu121380/article/details/82799835
#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define pb push_back
#define lowbit(x) x&(-x)
#define PII pair<int, int>
#define all(x) x.begin(), x.end()
#define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int mod = (int)1e9 + 7;
const int maxn = (int)1e5 + 5;
using namespace std;
ll sum[maxn];
char s[maxn];
int main()
{
int t; scanf("%d", &t);
while(t--){
scanf("%s", s + 1);
int len = strlen(s + 1);
for(int i = 1; i <= len; i++) sum[i] = 0;
for(int i = 1; i <= len; i++){
sum[i] = sum[i-1] + 1 + (s[i] == s[i-1]);
}
for(int i = 1; i <= len; i++){
sum[i] += sum[i-1];
}
ll ans = 0;
for(int i = 1; i <= len; i++){
if(s[i] == '0') ans += sum[len] - sum[i-1] - (sum[i] - sum[i-1] - 2) * (len - i + 1);
else ans += sum[len] - sum[i-1] - (sum[i] - sum[i-1] - 1) * (len - i + 1);
}
printf("%lld\n", ans);
}
return 0;
}
还有种写法,至今没弄懂
#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define pb push_back
#define lowbit(x) x&(-x)
#define PII pair<int, int>
#define all(x) x.begin(), x.end()
#define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int mod = (int)1e9 + 7;
const int maxn = (int)1e5 + 5;
using namespace std;
char s[maxn];
ll f[maxn];
int main()
{
int t; scanf("%d", &t);
while(t--){
scanf("%s", s);
int len = strlen(s);
for(int i = 1; i <= len; i++) f[i] = 0;
ll ans = 0;
f[1] = 1;
for(int i = 1; i < len; i++){
if(s[i] == s[i-1]) f[i+1] = 2;
else f[i+1] = 1;
}
for(int i = 1; i <= len; i++){
ans += f[i] * i * (len - i + 1);
if(s[i-1] == '0') ans += (len - i + 1);
if(f[i] == 2) ans -= (len - i + 1);
}
printf("%lld\n", ans);
}
return 0;
}
我真菜。
over