文章目录
- Problem [C. Move Brackets](https://codeforces.com/contest/1374/problem/C)
- Problem [A. Watermelon](https://codeforces.com/contest/4/problem/A)
- Problem [B. Cows and Poker Game](https://codeforces.com/contest/284/problem/B)
- Problem [C. ABBB](https://codeforces.com/contest/1428/problem/C)
- Problem [C. Long Jumps](https://codeforces.com/problemset/problem/1472/C)
- Problem [B. Jumps](https://codeforces.com/problemset/problem/1455/B)
- Problem [C. Sequence Transformation](https://codeforces.com/problemset/problem/1454/C)
Problem C. Move Brackets
给 定 n / 2 个 左 括 号 和 n / 2 个 右 括 号 , 每 次 可 以 把 某 个 括 号 移 动 到 括 号 序 列 的 最 左 端 或 末 尾 , 问 最 少 移 动 次 数 使 得 括 号 正 确 匹 配 , 题 目 保 证 有 解 我 们 只 需 要 求 有 多 少 对 括 号 没 有 匹 配 上 就 好 , 左 右 括 号 读 入 就 像 进 栈 一 样 给定n/2个左括号和n/2个右括号,每次可以把某个括号移动到括号序列的最左端或末尾,问最少移动次数\\使得括号正确匹配,题目保证有解\\ 我们只需要求有多少对括号没有匹配上就好,左右括号读入就像进栈一样 给定n/2个左括号和n/2个右括号,每次可以把某个括号移动到括号序列的最左端或末尾,问最少移动次数使得括号正确匹配,题目保证有解我们只需要求有多少对括号没有匹配上就好,左右括号读入就像进栈一样
#include<iostream>
#include<algorithm>
using namespace std;
int t;
int main()
{
cin>>t;
while(t--)
{
int n;
int ans=0;
cin>>n;
int cnta=0,cntb=0;//左括号数和右括号数
string a;
cin>>a;
for(int i=0;i<n;i++)
{
if(a[i]=='(')
cnta++;//扫描到了左括号,左括号入栈
else
{
cnta--;//扫描到了右括号,左括号数--
if(cnta<0)//如果栈内没有左括号,发现一个失配的右括号
{
cnta=0;//负数清空
ans++;//计数
}//如果cnta>=0说明正确匹配了
}
}
cout<<ans<<endl;
}
}
Problem A. Watermelon
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int w;
cin>>w;
if(w==2)cout<<"NO";
else if(w&1)
cout<<"NO";
else
cout<<"YES";
return 0;
}
Problem B. Cows and Poker Game
难 点 : H o w e v e r , s o a s n o t t o a f f e c t a n y b e t t i n g d e c i s i o n s , h e / s h e m a y o n l y d o s o i f a l l o t h e r p l a y e r s h a v e a s t a t u s o f e i t h e r " A L L I N " o r " F O L D E D " . 难点:However, so \ as\ not\ to\ affect\ any\ betting \ decisions, \ he/she\ may \ only \ do \ so \ if\\ all \ other\ players \ have \ a \ status\ of\ either\ "ALLIN" \ or \ "FOLDED". 难点:However,so as not to affect any betting decisions, he/she may only do so ifall other players have a status of either "ALLIN" or "FOLDED".
然 而 , 为 了 不 影 响 投 注 , 他 只 能 在 其 他 玩 家 都 是 A L L I N 或 者 F O L D E D 的 时 候 这 样 做 , ( 哪 样 做 呢 ? ) a p l a y e r w h o s e c u r r e n t s t a t u s i s n o t " F O L D E D " m a y s h o w h i s / h e r h a n d t o t h e t a b l e . 如 果 一 个 人 的 不 是 F , 那 么 他 就 展 示 手 牌 然而,为了不影响投注,他只能在其他玩家都是ALLIN或者FOLDED的时候这样做,(哪样做呢?)\\ a \ player\ whose \ current\ status \ is\ not \ "FOLDED" \ may \ show\ \\his/her \ hand \ to \ the \ table. 如 果一个人的不是F,那么他就展示手牌 然而,为了不影响投注,他只能在其他玩家都是ALLIN或者FOLDED的时候这样做,(哪样做呢?)a player whose current status is not "FOLDED" may show his/her hand to the table.如果一个人的不是F,那么他就展示手牌
// Problem: B. Cows and Poker Game
// Contest: Codeforces - Codeforces Round #174 (Div. 2)
// URL: https://codeforces.com/contest/284/problem/B
// Memory Limit: 256 MB
// Time Limit: 2000 ms
/*Love coding and thinking!*/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#include <vector>
#define pb push_back
#define mem(f, x) memset(f,x,sizeof(f))
#define fo(i,a,n) for(int i=(a);i<=(n);++i)
#define fo2(i,a,n) for(int i=(a);i<(n);++i)
#define debug(x) cout<<#x<<":"<<x<<endl;
#define endl '\n'
using namespace std;
typedef pair<int,int>PII;
typedef pair<long,long>PLL;
typedef long long ll;
typedef unsigned long long ull;
const int N=2e5+10,M=1e9+7;
int n,m,_;
int cnta,cntb,cntc;
int main()
{
cin>>n;
string s;cin>>s;
bool flag=1;
for(auto c:s)
{
if(c=='I')
cntc++,flag=false;
if(c=='I')
cnta++;
else if(c=='A')
cntb++;
}
if(flag)
cout<<cnta+cntb;
else if(cntc==1)
cout<<1;
else
cout<<0<<endl;
return 0;
}
Problem C. ABBB
给 一 个 串 , 把 串 中 的 子 串 " A B " , " B B " 删 去 , 问 还 剩 几 个 字 符 给一个串,把串中的子串"AB","BB"删去,问还剩几个字符 给一个串,把串中的子串"AB","BB"删去,问还剩几个字符
会T的写法
// Problem: C. ABBB
// Contest: Codeforces - Codeforces Raif Round 1 (Div. 1 + Div. 2)
// URL: https://codeforces.com/contest/1428/problem/C
// Memory Limit: 256 MB
// Time Limit: 1000 ms
/*Love coding and thinking!*/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#include <vector>
#define pb push_back
#define mem(f, x) memset(f,x,sizeof(f))
#define fo(i,a,n) for(int i=(a);i<=(n);++i)
#define fo2(i,a,n) for(int i=(a);i<(n);++i)
#define debug(x) cout<<#x<<":"<<x<<endl;
#define endl '\n'
using namespace std;
typedef pair<int,int>PII;
typedef pair<long,long>PLL;
typedef long long ll;
typedef unsigned long long ull;
const int N=2e5+10,M=1e9+7;
int n,m,_;
//AABB
int main()
{
cin>>_;
while(_--)
{
string s;cin>>s;
int t=s.find("AB");
while(s.size()&&t!=-1)
{
s.erase(t,2);
t=s.find("AB");
}
t=s.find("BB");
while(s.size()&&t!=-1)
{
s.erase(t,2);
t=s.find("BB");
}
cout<<s.size()<<endl;
}
return 0;
}
模拟栈即可
// Problem: C. ABBB
// Contest: Codeforces - Codeforces Raif Round 1 (Div. 1 + Div. 2)
// URL: https://codeforces.com/contest/1428/problem/C
// Memory Limit: 256 MB
// Time Limit: 1000 ms
/*Love coding and thinking!*/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#include <vector>
#define pb push_back
#define mem(f, x) memset(f,x,sizeof(f))
#define fo(i,a,n) for(int i=(a);i<=(n);++i)
#define fo2(i,a,n) for(int i=(a);i<(n);++i)
#define debug(x) cout<<#x<<":"<<x<<endl;
#define endl '\n'
using namespace std;
typedef pair<int,int>PII;
typedef pair<long,long>PLL;
typedef long long ll;
typedef unsigned long long ull;
const int N=2e5+10,M=1e9+7;
int n,m,_;
//AABB
int main()
{
cin>>_;
while(_--)
{
string s;cin>>s;
n=0;//模拟栈的大小
for(int i=0;i<s.size();i++)
{
// debug(i);
if(!n&&s[i]=='B')n++;//首个元素是b
else if(n&&s[i]=='B')
n--;
else
n++;
// debug(n);
}
cout<<n<<endl;
}
return 0;
}
Problem C. Long Jumps
给 定 n 个 数 , 权 值 为 a [ i ] , 可 以 选 择 n 个 起 跳 点 , 选 择 i 作 为 起 跳 点 a n s = a [ i ] + a [ i + a [ i ] ] + a [ a [ i + a [ i ] ] ] . . ( i + a [ i ] < = n ) 求 最 大 得 分 a n s 给定n个数,权值为a[i],可以选择n个起跳点,选择i作为起跳点\\ans=a[i]+a[i+a[i]]+a[a[i+a[i]]]..(i+a[i]<=n)\\ 求最大得分ans 给定n个数,权值为a[i],可以选择n个起跳点,选择i作为起跳点ans=a[i]+a[i+a[i]]+a[a[i+a[i]]]..(i+a[i]<=n)求最大得分ans
注 意 到 从 前 向 后 扫 描 每 个 起 跳 点 时 , 第 一 次 跳 到 某 个 点 一 定 比 第 二 次 跳 到 同 一 个 点 得 分 高 因 为 , 设 第 一 次 跳 到 某 个 点 X , 起 跳 起 点 为 l 1 , 第 二 次 跳 到 同 一 点 , 来 自 于 l 2 , 因 为 l 1 ! = l 2 且 l 1 是 率 先 跳 到 X 的 , 所 以 有 l 1 < l 2 , 所 以 有 从 l 1 起 跳 得 分 高 。 注意到从前向后扫描每个起跳点时,第一次跳到某个点一定比第二次跳到同一个点得分高\\ 因为,设第一次跳到某个点X,起跳起点为l_1,第二次跳到同一点,来自于l_2,因为l_1!=l_2\\ 且l_1是率先跳到X的,所以有l_1<l_2,所以有从l_1起跳得分高。 注意到从前向后扫描每个起跳点时,第一次跳到某个点一定比第二次跳到同一个点得分高因为,设第一次跳到某个点X,起跳起点为l1,第二次跳到同一点,来自于l2,因为l1!=l2且l1是率先跳到X的,所以有l1<l2,所以有从l1起跳得分高。
2021-01-13 11:39:58
#include<iostream>
#include<algorithm>
using namespace std;
typedef pair<int,int>PII;
const int N=2e5+10;
typedef long long ll;
int n,a[N];
bool st[N];
int main()
{
int t;cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i],st[i]=0;//使用st数组记录对于每个不同的起跳点,要跳到的那个点是不是
//第一次跳到了
ll ans=-1;
//注意到第一次跳到某个点一定比第二次跳到同一个点得分高
for(int i=1;i<=n;i++)
{
ll j=i,sum=0;
while(j<=n)
{
if(st[j])break;//不是第一次跳到的break
st[j]=1;//否则更新下sum,并记录
sum+=a[j];
j+=a[j];
}
ans=max(sum,ans);
}
cout<<ans<<endl;
}
return 0;
}
// Problem: C. Long Jumps
// Contest: Codeforces - Codeforces Round #693 (Div. 3)
// URL: https://codeforces.com/problemset/problem/1472/C
// Memory Limit: 256 MB
// Time Limit: 2000 ms
/*Love coding and thinking!*/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#include <vector>
#define pb push_back
#define mem(f, x) memset(f,x,sizeof(f))
#define fo(i,a,n) for(int i=(a);i<=(n);++i)
#define fo2(i,a,n) for(int i=(a);i<(n);++i)
#define debug(x) cout<<#x<<":"<<x<<endl;
#define endl '\n'
using namespace std;
typedef pair<int,int>PII;
typedef pair<long,long>PLL;
typedef long long ll;
typedef unsigned long long ull;
const int N=2e5+10,M=1e9+7;
int n,m,_;
ll a[N];
ll dp[N];//表示从i开始跳在满足规则(跳出界就停止)的所有可能方案中,能得到的最大价值,防止爆int
int main()
{
cin>>_;
while(_--)
{
cin>>n;
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
ll sum=0;
//dp[i]表示从1~i-1中某个点跳到该点
//DAG(有向无环图)上DP(动态规划)
// dp[i]=dp[i-a[i]]+a[i]; 这个和程序写的不一样,
//动态规划问题,dp数组(或者f数组)定义不同转移方程还有边界就会不同
// 这里dp[i]表示跳到i(和上边是不一样的)在满足规则(跳出界就停止)的所有可能方案中,能得到的最大价值
// 但是,i前边可能有很多点可以跳到i,还需要枚举,反而定义成从i开始跳只需要倒序扫一遍就行了
// dp[i+a[i]]=dp[i]+a[i+a[i]];
// for(int i=1;i<=n;i++)
// {
// dp[i]=a[i];
// if(i-a[i]>=1)
// {
// dp[i]+=dp[i-a[i]];
// }
// sum=max(sum,dp[i]);
// }
for(int i=n;i>=1;i--)
{
dp[i]=a[i];//从点i起跳,答案就是他自身
if(i+a[i]<=n)//如果不会出界
dp[i]+=dp[i+a[i]];//因为需要后边的子问题的答案,所以从后向前算
/*
什么叫需要后边的答案,所以需要从后向前算呢,因为dp[i]需要+=dp[i+a[i]],
而i+a[i]>i,但我们现在是在更新dp[i]的值,如果从小到大循环,那么我们现在在求
dp[i]的值,但我们需要知道dp[i+a[i]]的值,因为后边的没更新呢,只能是初始值0,
无法进行下去了,但是如果从后先前算,因为我们知道了大的就是dp[i+a[i]]的值,dp[i]
的值也就能推导了,1维的0/1背包和完全背包在代码上就是循环的方式不同,其余一样。
*/
sum=max(sum,dp[i]);
}
cout<<sum<<endl;
}
return 0;
}
Problem B. Jumps
初 始 时 位 于 坐 标 轴 远 点 , 想 要 移 动 到 X ( X > 0 ) , 第 k 步 移 动 要 不 从 p o s 位 置 向 x 正 方 向 移 动 k 步 , 要 么 回 退 一 步 。 询 问 到 达 目 标 点 X 的 最 小 跳 跃 步 数 初始时位于坐标轴远点,想要移动到X(X>0),第k步移动要不从pos位置向x正方向移动k步,要么回退一步。\\询问到达目标点X的最小跳跃步数 初始时位于坐标轴远点,想要移动到X(X>0),第k步移动要不从pos位置向x正方向移动k步,要么回退一步。询问到达目标点X的最小跳跃步数
贪心+构造,证明待补充 大佬链接
// Problem: B. Jumps
// Contest: Codeforces - Educational Codeforces Round 99 (Rated for Div. 2)
// URL: https://codeforces.com/problemset/problem/1455/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
/*Love coding and thinking!*/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#include <vector>
#define pb push_back
#define mem(f, x) memset(f,x,sizeof(f))
#define fo(i,a,n) for(int i=(a);i<=(n);++i)
#define fo2(i,a,n) for(int i=(a);i<(n);++i)
#define debug(x) cout<<#x<<":"<<x<<endl;
#define endl '\n'
using namespace std;
typedef pair<int,int>PII;
typedef pair<long,long>PLL;
typedef long long ll;
typedef unsigned long long ull;
const int N=3e6+10,M=1e9+7;
int n,m,_;
ll a[N];
int x;
int main()
{
cin>>_;
a[1]=1;
int i;
for(i=2;;i++)//初始化a数组,
{
a[i]=a[i-1]+i;
if(a[i]>1000000)
break;
}
n=i;//超过1e6的那个i
// cout<<n<<" "<<a[n]<<endl;
//1414 1000405
while(_--)
{
cin>>x;
int t=lower_bound(a+1,a+n,x)-a;//1 2 3 4 5 ... step 每次这么跳,二分找一下步数
if(a[t]==x)//刚好有可以通过1 2 3 4 5 这种方式跳到x的一步,输出是那一步就好
cout<<t<<endl;
else if(a[t]-1==x)//如果>=x的step步比x多1,需要在过程中返回走一步
cout<<t+1<<endl;
else//否则都可以通过在跳跃过程中选择合适的方式凑出x步
cout<<t<<endl;
}
return 0;
}
Problem C. Sequence Transformation
给 你 一 个 有 n 个 数 字 的 序 列 a , 为 了 使 操 作 后 序 列 中 剩 余 的 元 素 全 部 相 等 , 你 可 以 选 择 在 a 中 至 少 出 现 一 次 的 元 素 x 进 行 以 下 任 意 多 次 的 操 作 选 择 a 中 [ l , r ] , 要 求 [ l , r ] 中 没 有 元 素 a [ i ] = = x 将 [ l , r ] 区 间 从 a 中 移 除 , x 选 定 后 不 能 改 变 . 问 最 少 的 使 a 序 列 元 素 相 等 的 操 作 次 数 是 多 少 给你一个有n个数字的序列a,为了使操作后序列中剩余的元素全部相等,\\你可以选择在a中至少出现一次的元素x进行以下任意多次的操作\\选择a中[l,r],要求[l,r]中没有元素 a[i]==x 将[l,r]区间从a中移除,x选定后不能改变.问最少的使a序列元素相等的操作次数是多少 给你一个有n个数字的序列a,为了使操作后序列中剩余的元素全部相等,你可以选择在a中至少出现一次的元素x进行以下任意多次的操作选择a中[l,r],要求[l,r]中没有元素a[i]==x将[l,r]区间从a中移除,x选定后不能改变.问最少的使a序列元素相等的操作次数是多少
#include<string>
#include<iostream>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=2e5+10;
/*
有了思路之后,怎么最快速的实现
将数组使用unique去重,统计每个元素出现的次数,
*/
int a[N];
map<int,int>mp;
int main()
{
int t;
cin>>t;
while(t--)
{
int n;cin>>n;
mp.clear();
memset(a,0,sizeof a);
for(int i=0;i<n;i++)
cin>>a[i];
int m=unique(a,a+n)-a;
// cout<<m<<endl;
if(m==1)//去重后只有一个元素
cout<<"0"<<endl;
else
{
for(int i=0;i<m;i++)
{
if(i==0||i==m-1)//类似隔板法
mp[a[i]]--;//不统计最前面和最后边的元素
mp[a[i]]++;
}
int Min=1e7;
for(auto x:mp)
{
Min=min(Min,x.second+1);
}
cout<<Min<<endl;
}
}
return 0;
}