1.A. Gift Carpet
题意:
给定n行m列的矩阵,问是否可以得到从左往右的四个序列(可以不用连续),第一列中包含‘v’,第二列中包含‘i’,第三列中包含‘k’,第四列中包含‘a’。
思路:
直接枚举,用flag标记即可。(题意理解错了琢磨挺久┭┮﹏┭┮)
AC代码:
//gyeolhada...in bloom...dream...ricky
//string s="ricky";s.insert(0,"hello ");-->hello ricky
//transform(s.begin(), s.end(), s.begin(), ::tolower);
//2^30=1e9+73741824
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define sall(x) (x).begin(),(x).end()
#define ball(x) (x).rbegin(),(x).rend()
#define pii pair<int,int>
#define pll pair<ll,ll>
#define inf 0x3f3f3f3f3f3f3f3f
#define Y cout<<"YES"<<endl
#define N cout<<"NO"<<endl
const int M=25;
char a[M][M];
void ZB1()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
bool flag1=0,flag2=0,flag3=0,flag4=0;
for(int j=1;j<=m;j++)
{
for(int i=1;i<=n;i++)
{
if(!flag1&&a[i][j]=='v')
{
flag1=1;
break;
}
if(flag1&&!flag2&&a[i][j]=='i')
{
flag2=1;
break;
}
if(!flag3&&flag1&&flag2&&a[i][j]=='k')
{
flag3=1;
break;
}
if(!flag4&&flag3&&flag1&&flag2&&a[i][j]=='a')
{
flag4=1;
break;
}
}
}
if(flag1&&flag2&&flag3&&flag4)Y;
else N;
}
int main()
{
int t;
cin >> t;
while (t--)
{
ZB1();
}
return 0;
}
2.B. Sequence Game
题意:
给定一个长度为n的序列b,求满足a1=b1且对于后面的每个ai都有a[i-1]<=a[i]的序列a,规定a的长度m(n<=m<=2*m)。
思路:
枚举b,若b[i]>=b[i-1]直接放个b[i]进a,否则放两个b[i]。
AC代码:
//gyeolhada...in bloom...dream...ricky
//string s="ricky";s.insert(0,"hello ");-->hello ricky
//transform(s.begin(), s.end(), s.begin(), ::tolower);
//2^30=1e9+73741824
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define sall(x) (x).begin(),(x).end()
#define ball(x) (x).rbegin(),(x).rend()
#define pii pair<int,int>
#define pll pair<ll,ll>
#define inf 0x3f3f3f3f3f3f3f3f
#define Y cout<<"YES"<<endl
#define N cout<<"NO"<<endl
void ZB1()
{
int n;
cin>>n;
vector<ll>b(n);
for(int i=0;i<n;i++)cin>>b[i];
vector<ll>a;
a.push_back(b[0]);
for(int i=1;i<n;i++)
{
if(b[i]>=b[i-1])a.push_back(b[i]);
else
{a.push_back(b[i]),
a.push_back(b[i]);}
}
cout<<a.size()<<endl;
for(int i=0;i<a.size();i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
int main()
{
int t;
cin >> t;
while (t--)
{
ZB1();
}
return 0;
}
3.C. Flower City Fence
题意:
给定一个长度为n的序列a,且满足a1>=a2>=a3>=...>=an,判断将a序列各个值水平摆放后得到的序列b是否与序列a相同。
例如a=[4,2,1]--->b[3,2,1,1]
思路:
首先如果a[1]最大的数与n不相同就直接N,接着将b数组初始为0,然后每个a[i]的值对应b的下标,每个所对应的下标a的b的值++(先加上差值),之后将b从后往前,b[i]=b[i]+b[i+1]前面的加上后面的,确保堆得起来,最后再判断a与b是否相同即可。
AC代码:
//gyeolhada...in bloom...dream...ricky
//string s="ricky";s.insert(0,"hello ");-->hello ricky
//transform(s.begin(), s.end(), s.begin(), ::tolower);
//2^30=1e9+73741824
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define sall(x) (x).begin(),(x).end()
#define ball(x) (x).rbegin(),(x).rend()
#define pii pair<int,int>
#define pll pair<ll,ll>
#define inf 0x3f3f3f3f3f3f3f3f
#define Y cout<<"YES"<<endl
#define N cout<<"NO"<<endl
void ZB1()
{
int n;
cin>>n;
vector<ll>a(n+1);
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
if(a[1]!=n)
{
N;
return;
}
vector<ll>b(a[1]+1,0);
for(int i=1;i<=n;i++)//b的下标a[i]那条肯定至少为高1
{
b[a[i]]++;
}
//枚举b
for(int i=n-1;i>=1;i--)
{
b[i]=b[i]+b[i+1];
}
for(int i=1;i<=n;i++)
{
if(a[i]!=b[i])
{
N;
return;
}
}
Y;
}
int main()
{
int t;
cin >> t;
while (t--)
{
ZB1();
}
return 0;
}
4.D. Ice Cream Balls
题意:
给一个数字n,n表示n种不同的冰激凌即n种不同的两个数字的组合(两个数字可以相同,可以不同),求最少要买多少个球即最少需要多少个数字。
思路:
由1~m个不同数字两两组合,可得组合总数为m*(m+1)/2==n,m*(m+1)==n*2
AC代码:
//gyeolhada...in bloom...dream...ricky
//string s="ricky";s.insert(0,"hello ");-->hello ricky
//transform(s.begin(), s.end(), s.begin(), ::tolower);
//2^30=1e9+73741824
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define sall(x) (x).begin(),(x).end()
#define ball(x) (x).rbegin(),(x).rend()
#define pii pair<int,int>
#define pll pair<ll,ll>
#define inf 0x3f3f3f3f3f3f3f3f
#define Y cout<<"YES"<<endl
#define N cout<<"NO"<<endl
void ZB1()
{
ll n;
cin>>n;
if(n==1)
{
cout<<2<<endl;
return;
}
ll d=(ll)sqrtl(2*n);
while(d*(d+1)/2<=n)d++;
cout<<n+d-d*(d-1)/2<<endl;
}
int main()
{
int t;
cin >> t;
while (t--)
{
ZB1();
}
return 0;
}
5.E. Kolya and Movie Theatre
题意:
给定长度为n的序列a,以及m和d,在a中可选m个数,使得娱乐值最大。娱乐值=选择的a里的m个数-d*(选择的在a中下标最大的那个数的下标),注意a中下标从1开始。
思路:
定义一个s,a从前往后枚举,只要a[i]>=0,s就加上a[i],同时加入小根堆,如果堆的数目大于m就弹出堆顶最小值s减去这个最小值,这样能保证我们的答案最大,每次操作后都取一下mx=max(mx,s-d*(i+1))
AC代码:
//gyeolhada...in bloom...dream...ricky
//string s="ricky";s.insert(0,"hello ");-->hello ricky
//transform(s.begin(), s.end(), s.begin(), ::tolower);
//2^30=1e9+73741824
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define sall(x) (x).begin(),(x).end()
#define ball(x) (x).rbegin(),(x).rend()
#define pii pair<int,int>
#define pll pair<ll,ll>
#define inf 0x3f3f3f3f3f3f3f3f
#define Y cout<<"YES"<<endl
#define N cout<<"NO"<<endl
void ZB1()
{
ll n,m,d;
cin>>n>>m>>d;
vector<ll>a(n);
for(int i=0;i<n;i++)
{
cin>>a[i];
}
priority_queue<ll,vector<ll>,greater<ll>>h;
ll mx=0,s=0;
for(int i=0;i<n;i++)
{
if(a[i]>=0)
{
s+=a[i];
h.push(a[i]);
}
if(h.size()>m)//删去最小的
{
s-=h.top();
h.pop();
}
mx=max(mx,s-1ll*d*(i+1));//不断取最大值
}
cout<<mx<<endl;
}
int main()
{
int t;
cin >> t;
while (t--)
{
ZB1();
}
return 0;
}