其实人家是模拟。。。(思路)(统计cow出现的次数)
2016-08-22 15:49
344 查看
链接:http://exam.upc.edu.cn/problem.php?cid=1105&pid=7
题意:给以个长度为n的字符串,其中只有c,o,w三个字母。统计cow出现的次数,可以中间夹字母,但顺序必须是对的。如:cowc ,1.coowww,6
解析:如果当前点是o,那么co的个数只与前面出现过的c的个数有关。如果当前点是w,cow的个数只与前面co个数有关。将所有当前点是w的个数相加,即为所求。。。。
先是我巨丑的代码:(统计没点的个数,如果当前点是c,sum[i]表示的就是1,如果当前点是o,sum[i]表示的以当前点为结尾,co的个数。所以需要统计所有以o为结尾的sum和。再次计算后当前点为o,sum[i]表示包括当前点在内的所有co的个数。如果当前点是w,只需看在离他最近的它之前的o的个数即可。最后统计所有点是w的sum和。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
char s[100006];
long long dp[100006];
long long sum[100006];
long long p[100006];
int main()
{
// freopen("in.txt","r",stdin);
int n;
scanf("%d",&n);
scanf("%s",s);
int k = 0;
int last;
for(int i = 0; i < n; i ++)
{
if(s[i] == 'C')
sum[i] ++;
if(i != 0)
sum[i] += sum[i - 1];
if(s[i] == 'O')
{
if(k == 0)
p[i] = -1;
else
p[i] = last;
k ++;
last = i;
}
}
last = -1;
for(int i = 0; i < n; i ++)
{
if(s[i] == 'O')
{
if(p[i] != -1)
dp[i] = sum[i] + dp[p[i]];
else
dp[i] = sum[i];
last = i;
}
else if(s[i] == 'W')
{
dp[i] = dp[last];
//cout<<dp[i]<<endl;
}
}
long long ans = 0;
for(int i = 0; i<n; i ++)
{
if(s[i] == 'W')
{
ans += dp[i];
}
}
printf("%lld\n",ans);
return 0;
}
因为开始时认为此题dp,所以一直都是dp的思路,改得很丑。其实根本不用这么麻烦,直接统计c的个数,co的个数,cow的个数。如果当前点是c,c的个数加一。如果当前点是o,co的个数增加再它左侧c的个数。如果当前点是w,cow的个数增加在它左侧co的个数。。。。
本质是一样的,代码好写很多。。。(注:不是我自己写的。。。不过就那么三行,重写也没什么意思)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#include<functional>
#define mod 1000000007
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int N=100005;
const int M=15005;
char s
;
int n,m;
ll sc=0,sco=0,scow=0;
int main(){
scanf("%d%s",&n,s);
for(int i=0;i<n;i++){
if(s[i]=='C')sc++;
if(s[i]=='O')sco+=sc;
if(s[i]=='W')scow+=sco;
}
printf("%lld\n",scow);
return 0;
}
题意:给以个长度为n的字符串,其中只有c,o,w三个字母。统计cow出现的次数,可以中间夹字母,但顺序必须是对的。如:cowc ,1.coowww,6
解析:如果当前点是o,那么co的个数只与前面出现过的c的个数有关。如果当前点是w,cow的个数只与前面co个数有关。将所有当前点是w的个数相加,即为所求。。。。
先是我巨丑的代码:(统计没点的个数,如果当前点是c,sum[i]表示的就是1,如果当前点是o,sum[i]表示的以当前点为结尾,co的个数。所以需要统计所有以o为结尾的sum和。再次计算后当前点为o,sum[i]表示包括当前点在内的所有co的个数。如果当前点是w,只需看在离他最近的它之前的o的个数即可。最后统计所有点是w的sum和。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
char s[100006];
long long dp[100006];
long long sum[100006];
long long p[100006];
int main()
{
// freopen("in.txt","r",stdin);
int n;
scanf("%d",&n);
scanf("%s",s);
int k = 0;
int last;
for(int i = 0; i < n; i ++)
{
if(s[i] == 'C')
sum[i] ++;
if(i != 0)
sum[i] += sum[i - 1];
if(s[i] == 'O')
{
if(k == 0)
p[i] = -1;
else
p[i] = last;
k ++;
last = i;
}
}
last = -1;
for(int i = 0; i < n; i ++)
{
if(s[i] == 'O')
{
if(p[i] != -1)
dp[i] = sum[i] + dp[p[i]];
else
dp[i] = sum[i];
last = i;
}
else if(s[i] == 'W')
{
dp[i] = dp[last];
//cout<<dp[i]<<endl;
}
}
long long ans = 0;
for(int i = 0; i<n; i ++)
{
if(s[i] == 'W')
{
ans += dp[i];
}
}
printf("%lld\n",ans);
return 0;
}
因为开始时认为此题dp,所以一直都是dp的思路,改得很丑。其实根本不用这么麻烦,直接统计c的个数,co的个数,cow的个数。如果当前点是c,c的个数加一。如果当前点是o,co的个数增加再它左侧c的个数。如果当前点是w,cow的个数增加在它左侧co的个数。。。。
本质是一样的,代码好写很多。。。(注:不是我自己写的。。。不过就那么三行,重写也没什么意思)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#include<functional>
#define mod 1000000007
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int N=100005;
const int M=15005;
char s
;
int n,m;
ll sc=0,sco=0,scow=0;
int main(){
scanf("%d%s",&n,s);
for(int i=0;i<n;i++){
if(s[i]=='C')sc++;
if(s[i]=='O')sco+=sc;
if(s[i]=='W')scow+=sco;
}
printf("%lld\n",scow);
return 0;
}
相关文章推荐
- Excel 中统计某个项目出现的次数,以及模拟SQL的Group by效果
- "分拣" 思路 统计每个单词出现的次数
- JavaScript中模拟java的map键值统计一段英文中各个单词出现的次数
- 统计一个字符串中字符出现的次数(带上机课时候发现学生都有很好的思路bitmap)
- HDU 1800 简单贪心 13.1.10用trie重做 ---其实是统计出现次数最多的单词
- Java统计一篇英文单词出现次数
- go语言之map练习(二):编写一个程序wordfreq程序,统计输入文本中每个单词出现的频率(次数)
- 输入一行字符串统计各字符出现的次数
- 如何读取CSV文件,格式化数据,统计生日出现的次数
- 前端面试题:统计每一个标签出现的次数
- 统计字母A出现的次数
- 计数:统计出现的次数
- 字符串压缩--统计字符出现的最大次数
- 排序一个列表序列,并统计每一个元素出现的次数
- java统计字符串中单个字符出现的次数
- 统计字母'A'和 数字 出现的次数;
- linux命令 对日志文件的IP出现的次数进行统计 并显示次数最多的前六名
- java小练习之统计字符串中字符出现的次数
- C语言 输入字符并统计出现次数(练习)
- list集合统计元素出现的次数