标签:数据 后缀 前缀 random 查找 map 回文 因此 return
比赛链接:https://codeforces.ml/contest/1461
给定字符长度和最大回文子串长度,输出一个由‘a‘,‘b‘,‘c‘构成的字符串。
解题代码:
#include <iostream>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;
cin >> t;
while(t--){
int n,k;
cin >> n >> k;
int cnt = 0;
for(int i = 0;i<n;i++){
cout << char(‘a‘+cnt%3);
cnt++;
}
cout << endl;
}
return 0;
}
给定一个矩阵,由‘*‘和‘.‘构成,数一下其中有多少个下面的结构。每个枚举会超时,解题思路是每次遍历矩阵,将不被三环绕的点删除。
解题代码:
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 520;
char a[maxn][maxn];
int td = 0;
int count(int n,int m){
int tres = 0;
int b[maxn][maxn] = {0};
//memset(b,0,sizeof(b));
for(int i = 1;i<=n;i++){
for(int j = 1;j<=m;j++){
if(a[i][j] == ‘*‘){
tres++;
if(a[i-1][j]==‘*‘&&a[i][j-1]==‘*‘&&a[i][j+1]==‘*‘){
b[i][j] = 1;
}
}
}
}
for(int i = 1;i<=n;i++){
for(int j = 1;j<=m;j++){
if(a[i][j] == ‘*‘){
if(b[i][j]!=1){
a[i][j] = ‘.‘;
td -= 1;
}
}
}
}
return tres;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;
cin >> t;
while(t--){
int n,m;
cin >> n >> m;
memset(a,0,sizeof(a));
int res = 0;
for(int i = 1;i<=n;i++){
for(int j = 1;j<=m;j++){
cin >> a[i][j];
if(a[i][j]==‘*‘)td+=1;
}
}
while(td!=0){
res += count(n,m);
}
cout << res << endl;
}
return 0;
}
一个长度为n的数组,对其进行m次操作,每次有p的概率使前r个有序,问其最终有序的概率是多少
分析:如果后缀无序,前缀有序,无用,所以要从后缀开始处理,反推每一个有影响的实验都不发生,最后用1减去不满足的概率即满足的概率
补题代码:
#include <iostream>
using namespace std;
const int maxn = 1e5 + 5;
int a[maxn];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;
cin >> t;
while(t--){
int n,m,k = 0;
cin >> n >> m;
for(int i = 1;i<=n;i++){
cin >> a[i];
}
for(int i = n;i>1;i--){
if(a[i]!=i){
k = i;//找到最小有效变动的位置
break;
}
}
double res = 1;
while(m--){
int r;
double p;
cin >> r >> p;
if(r<k) continue;
else res *= (1-p); //每次有效操作都不进行的概率
}
if(k==0) res = 0;//如果本身有序,就不用进行操作了
printf("%.6f\n",1.0-res);
}
}
对于一个数列,可以进行操作以数列中最大值和最小值和的一般作为分界线,划分为左半部分和右半部分,询问是否可以使其中一个序列的元素和为s。
错误原因分析:思路错误,并非在需要查找时在进行查找操作,而是需要使用map记录可以找到的所有数值,查找时判断是否可以找到即可,c++中封装了而非查找的程序,因此在本题中并不需要手写二分查找,占用时间,题目给出的测试数据较大需要使用long long进行存储。
补题代码:
#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
int a[maxn];
ll sum[maxn];
map<ll,int> mp;
void solve(int l,int r){
//此处mid记录的是 mina和maxa 的中值的位置
//位运算的优先级比加减运算更低,所以a[l]+a[r]>>1等价于(a[l]+a[r])/2
//upper_bound()返回的是一个地址,通过减去a的地址可以计算得到中间位置
int mid = upper_bound(a+1,a+r+1,a[l]+a[r]>>1)-a;
//递归记录每一个可能出现的值
if(a[l]!=a[r])solve(l,mid-1), solve(mid,r);
//将每一个出现的值在mp中记录,便于查找
mp[sum[r]-sum[l-1]] = 1;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;
cin >> t;
int n,m;
while(t--){
mp.clear();
cin >> n >> m;
for(int i = 1;i<=n;i++)cin >> a[i];
sort(a+1,a+n+1);
sum[0] = 0;
for(int i = 1;i<=n;i++)sum[i] = sum[i-1]+a[i];
solve(1,n);
while(m--){
int s;
cin >> s;
if(mp[s])cout << "Yes\n";
else cout << "No\n";
}
}
}
标签:数据 后缀 前缀 random 查找 map 回文 因此 return
原文地址:https://www.cnblogs.com/simulatedsakura/p/14123808.html