就是说n个对战夜吹说他赢了几把,连胜了几把看有没有可能,有就输出yes+方案,没有就输出no
分类讨论,想什么时候就是在吹。(题目保证n>=m>=k)
#include
using namespace std;
int main()
{
int n, m, k; cin >> n >> m >> k;
if (k == 0)
{
if (m == 0) {
cout << "YES\n";
for (int i = 0; i < n; i++)cout << 0;
}
else cout << "NO\n";
}
else
{
if (m == k) {
cout << "YES\n";
for (int i = 0; i < n; i++)
{
if (i < m)cout << 1; else cout << 0;
}
}
else
{
if (n == m)
{
if (k != m)cout << "NO\n";
else
{
for (int i = 0; i < n; i++)cout << 1;
}
}
else
{
int a = n - m, b = m - k;
int c = a;int e=k;
if (c * k >= b)
{
cout << "YES\n";
while (k--)cout << 1;
while (b>0)
{
int d = e;
cout << 0; a--;
while (d--&&b>0) { cout << 1; b--; }
}
while (a--)cout << 0;
}
else cout << "NO\n";
}
}
}
}
其中 A
代表进攻, B
代表防御,C
代表蓄力。
如果 Hammer 可以击杀电脑,则输出一个整数,表示 Hammer 能得到的最高得分。
否则结局一定是平局,(不然 Hammer 的透视挂岂不是白买了!)输出 draw
。
1.当机器人进攻时我们只能防御;
2.当机器人防御时我们可以蓄力得到高分
3.当机器人蓄力时我们可以蓄力,也可以进攻如果有能量。为了得到最高分,我们就必须在最后机器人蓄力的时候击杀它,否则杀不掉。
综上我们要记遍历录下C最后的位置同时统计C的数量,然后遍历到C最后的位置统计B的数目,如果能量为0,那么杀不掉。
同时特判如果没有C也是杀不掉。
#include
#include
#include
using namespace std;
int main()
{
int n;
cin>>n;
string a;
cin>>a;
int cnt=0;
int ans=-1;
int jj=0;
for(int i=0;i<n;i++){if(a[i]=='C'){ans=i;cnt++;}}
for(int i=0;i<ans;i++){if(a[i]=='B')jj++;}
if(cnt+jj-1<=0||ans==-1)cout<<"draw";
else cout<<cnt+jj-2;
}
对一个长度为n的初始元素为0的数组进行修改,每次选择一个位置x,一个正整数y,将数组每个数加上max(y-abs(x-i),0),经过q此修改后数组是什么
通过观察我们可以发现,有些位置不会受到影响还是原来的值0,通过计算我们可以得到对于一次操作,
- 最左端影响到L=max(x-y,1)
- 最右端影响到R=min(x+y,n)
最大长度为2y,然后进行修改即可
#include
using namespace std;
const int N = 1e5+10;
int a[N];
int main()
{
int n,q;
cin>>n>>q;
while(q--){
int x,y;
cin>>x>>y;
int l = max(x-y,1);
int r = min(x+y,n);
for(int i = l;i<=r;i++)
{
a[i] +=max(y-abs(x-i),0);
}
}
for(int i = 1;i<=n;i++)
cout<<a[i]<<" ";
return 0;
}
n个数中选择n-1个数进行|运算然后又n种选择,输出n个方案的最大值,注意数据范围
构造前缀或,后缀或,算出n种答案,选最大值
#include
#include
#include
#include
#include
#include
using namespace std;
long long a[210000],b[210000],c[210000];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++) {
cin>>a[i];
b[i]=a[i];
c[i]=a[i];
}
for(int i=2;i<=n;i++)
{
b[i]=b[i]|b[i-1];
}
for(int i=n-1;i>=2;i--){
c[i]=c[i]|c[i+1];
}
long long ans=0;
for(int i=2;i<n;i++){
ans=max(ans,b[i-1]|c[i+1]);
}
ans=max(ans,c[2]);
ans=max(ans,b[n-1]);
cout<<ans;
return 0;
}
给定一个彩票刮开了一部分,只有仅有k个1连在一起才算中奖,输出可能个数,没有则输出delicious
创建滑动窗口统计k区间内是否都是1,外面是否都是0,计数即可。
#include
using namespace std;
#define fi first
#define se second
#define endl "\n"
#define ll long long
#define ull unsigned ll
#define pb push_back
#define all(v) v.begin(),v.end()
#define PII pair<int,int>
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i=(int)a,i##i=(int)b;i<=i##i;i++)
#define per(i,a,b) for(int i=(int)a,i##i=(int)b;i>=i##i;i--)
const int N=1e5+5;
int c0[N],c1[N];
void solve(){
int n,k; cin>>n>>k;
string s; cin>>s; s=" "+s;
rep(i,1,n){
c0[i]=c0[i-1]+(s[i]=='0');
c1[i]=c1[i-1]+(s[i]=='1');
}
int ans=0;
rep(i,k,n){
if(c0[i]-c0[i-k]==0&&!c1[i-k]&&!(c1[n]-c1[i])) ans++;
}
if(ans) cout<<ans<<endl;
else cout<<"delicious"<<endl;
}
int main(){
IOS;
int T=1;
while(T--) solve();
}
给一个字符串修改一个字符成为字典序最小的回文串
因为题目给了只需修改一个字符,则证明只有一个字符不同当字符串长度为偶数时,找到不同的位置看那个字典序小就换成那个。奇数时把中间位置字符换掉,如果为a则换成b否则都换成a。
#include
using namespace std;
int main()
{
int n;cin>>n;
string a;cin>>a;
vector<int>b(n);
char c,d;
int j=0;
int cnt=0,ans;
for(int i=0;i<n/2;i++)
{
if(a[i]!=a[n-1-i]){
c=a[i],d=a[n-1-i];
cnt=i,ans=n-1-i;
j++;
}
}
if(j>0){
if(c>d){
for(int i=0;i<n;i++)
{
if(i==cnt)cout<<d;
else cout<<a[i];
}}
else
{
for(int i=0;i<n;i++)
{
if(i==ans)cout<<c;
else cout<<a[i];
}
}}
else{
for(int i=0;i<n;i++)
{if(i==n/2&&a[i]!='a')cout<<'a';
else
if(i==n/2&&a[i]=='a')cout<<'b';
else cout<<a[i];
}
}}
n个数字轮流选择一个数字和它的因子,谁不能拿了就赢了。
,可以暴力搜索+特判。
但可以发现只有1时bob赢
#include
using namespace std;
int main()
{
int n;cin>>n;
if(n>=2)cout<<"Alice";
else cout<<"Bob";
}
如果字符串有eat就输出eeffQAQ否则输出What does it mean?
find 找一下位置,或者strstr
#include
using namespace std;
int main()
{
string a;
cin>>a;
if(a.find("eat")<=1000)cout<<"eeffQAQ";
else cout<<"What does it mean?";
}
有n个停车位,由于车主们害怕刮蹭,所以每次停车都停在离别的车最远的地方,特别的第一辆车停在最左边。问可以停多少车
这个问题和广大男同胞上厕所有着大同小异的关系。
是一个坑位利用率的问题。怎么解决呢?
我们不难发现n=1时可以停1个即f(1)=1,f(2)=1,f(3)=2,f(4)=2;
打表可以发现规律a[i]=a[i/2]+a[i/2+1]-1;
a[i]=a[(i+1)/2]*2-1;
同时我们也可以想到当n大于2时每停一辆车都必须在两辆车之间停,所以就看看两辆车之间的距离能放多少车。
#include
using namespace std;
int a[1000001];
int main()
{
int n;
cin>>n;
a[1]=1;a[2]=1;a[3]=2;a[4]=2;
if(n>4)
{
for(int i=5;i<=(n/2+1);i++)
{
if(i%2==0) a[i]=a[i/2]+a[i/2+1]-1;
else a[i]=a[(i+1)/2]*2-1;
}
if(n%2==0) a[n]=a[n/2]+a[n/2+1]-1;
else a[n]=a[(n+1)/2]*2-1;
}
cout<<a[n]<<endl;
}
每24小时必须吃一顿,给出一日三餐热量使得结束时热量最小
可以动态规划,从第一天吃早午晚饭记录下每次选择的方案到最后比最小。
同时也可以进行贪心先选择第一天最小的,然后选择这一天后三顿最小的,继续选择,可以用queue实现。
#include
using namespace std;
int d[100005][3];
int main()
{
int n,i,j;
cin>>n;
for(i=1;i<=n;i++)
cin>>d[i][0]>>d[i][1]>>d[i][2];
for(i=n-1;i>=1;i--)
{
d[i][2]+=min(d[i+1][0],min(d[i+1][1],d[i+1][2]));
d[i][1]+=min(d[i+1][1],min(d[i][2],d[i+1][0]));
d[i][0]+=min(d[i+1][0],min(d[i][1],d[i][2]));
}
cout<<min(d[1][0],min(d[1][1],d[1][2]));
return 0;
}
给两个数字竖式向左对齐相加
少的位数补0相加即可
#include
using namespace std;
#define int long long
int shu(int n)
{
int cnt=0;
while(n)
{
cnt++;
n/=10;
}
return cnt;
}
int ss(int u)
{
int sum=1;
while(u--)sum*=10;
return sum;
}
signed main()
{
int a,b;
cin>>a>>b;
int c=shu(a);
int d=shu(b);
if(c>d){b=b*ss(c-d);cout<<a+b;}
if(c==d)cout<<a+b;
if(c<d){a=a*ss(d-c);cout<<a+b;}
}