题解:按题意模拟即可
/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include
const int maxn = 3100;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 1000007;
using namespace std;
string s;
int main()
{
int t;
cin>>t;
while(t--){
cin>>s;
if(s.size()==2){
cout<<s<<endl;
continue ;
}
cout<<s[0];
for(int i=1;i<s.size()-1;i+=2){
cout<<s[i];
}
cout<<s[s.size()-1]<<endl;
}
return 0;
}
判断一下不符合条件的情况,看看两种不符合条件的情况是否相等,如果相等即可调换,不相等输出-1.
/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include
const int maxn = 3100;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 1000007;
using namespace std;
int a[maxn];
int main()
{
int t;
cin>>t;
while(t--){
int n;
cin>>n;
int cnt=0,cnt1=0;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
if(a[i]%2==0&&i%2!=0) cnt++;
if(a[i]%2!=0&&i%2==0) cnt1++;
}
if(cnt!=cnt1) cout<<-1<<endl;
else cout<<cnt<<endl;
}
return 0;
}
题解:我们把有1的地方扩散一下,也就是假设第i个地方是1,那么i到i+k和i+k是都不可以做人的,那么我们把不能做人的地方用#打个标记即可,然后寻找有0的地方,并且没次在0的地方坐下一个客人,位置要向前移动k个。
/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include
const int maxn = 3100;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 1000007;
using namespace std;
string s;
int main()
{
int t,k,n;
cin>>t;
while(t--){
cin>>n>>k;
cin>>s;
for(int i=0;i<n;i++){
if(s[i]=='1'){
for(int j=max(0,i-k);j<=min(n-1,i+k);j++){
s[j]='#';
}
}
}
int ans=0;
for(int i=0;i<n;i++){
if(s[i]=='0'){
ans++;
i+=k;
}
}
cout<<ans<<endl;
}
return 0;
}
感觉这个题目涉及了一点点思维,但是模拟起来细节有点多。
思路:对于0的位置,字母一定是最大的,对于字母第二大的元素,他只会受第一大字母的影响,同理,第三大字母只受比他大的字母的影响。
所以我们遍历每个位置看看,某个字母是否符合这个位置的b数组的大小
还有一个小细节,就是我们需要看看这个字母最多能匹配多少个位置,如果位置的个数大于当前字母的个数,说明这个字母不可以用。
/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include
const int maxn = 3100;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 1000007;
using namespace std;
char ans[maxn];
string s;
int visited[maxn],cnt[maxn];
int a[maxn];
int main()
{
int t;
cin>>t;
while(t--){
cin>>s;
int n,z=0;
cin>>n;
memset(cnt,0,sizeof(cnt));
memset(visited,false,sizeof(visited));
char imax='a';
for(int i=0;i<s.size();i++){
cnt[s[i]-'a']++;
if(imax<s[i]) imax=s[i];
}
for(int i=0;i<n;i++) scanf("%d",&a[i]);
for(int i=0;i<n;i++){
if(!a[i]) visited[i]=true,z++;
}
for(int i=25;i>=0;i--){
if(cnt[i]>=z){
for(int j=0;j<n;j++) if(!a[j]) ans[j]=i+'a';
cnt[i]=0;
break;
}
cnt[i]=0;
}
for(int i=25;i>=0;i--){
if(cnt[i]!=0){
int x=0;
for(int j=0;j<n;j++){
if(!visited[j]){
int sum=0;
for(int k=0;k<n;k++){
if(visited[k]&&ans[k]>i+'a'){
sum+=abs(j-k);
}
}
if(sum==a[j]){
visited[j]=true;
x++;
ans[j]=i+'a';
}
}
}
if(x>cnt[i]){
for(int j=0;j<n;j++){
if(ans[j]==i+'a') visited[j]=false;
}
}
}
}
for(int i=0;i<n;i++) printf("%c",ans[i]);
printf("\n");
}
return 0;
}
做的时候也想到过跟因子有关,可惜太菜了,没想出来。
参考了这个大佬的思路:https://www.bilibili.com/video/BV1xT4y1J7yd?p=2
/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include
const int maxn = 3100;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 1000007;
using namespace std;
string s;
int cnt[maxn];
int main()
{
int t;
cin>>t;
while(t--){
int n,k;
cin>>n>>k;
cin>>s;
memset(cnt,0,sizeof(cnt));
for(int i=0;i<s.size();i++){
cnt[s[i]-'a']++;
}
vector<int> v;
for(int i=1;i<=k;i++){
if(k%i==0) v.push_back(i);
}
int ans=0;
for(int i=1;i<=n;i++){
for(auto x : v){
if(x%i==0){
ans=max(ans,i);
}
if(i%x==0){
int dx=i/x;
int cnt1=0;
for(int j=0;j<26;j++){
cnt1+=cnt[j]/dx;
}
if(cnt1>=x){
ans=max(ans,i);
}
}
}
}
cout<<ans<<endl;
}
return 0;
}
本题数据较大,所以要事先离散化一下,为什么可以这样离散化,是因为条件给出了每个数字最多出现一次,所以我们把他按照由小到大的顺序分别代表1-n的数字。
在用dp求出最长上升子序列即可。
/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include
const int maxn = 3100;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 1000007;
using namespace std;
int dp[maxn];
int a[maxn],b[maxn];
map<int,int> mp;
int main()
{
int t;
cin>>t;
while(t--){
int n;
cin>>n;
memset(dp,0,sizeof(dp));
mp.clear();
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
mp[b[i]]=i;
}
sort(b,b+n);
for(int i=0;i<n;i++){
a[mp[b[i]]]=i;
}
int imax=1;
for(int i=0;i<n;i++){
dp[a[i]]=dp[a[i]-1]+1;
imax=max(imax,dp[a[i]]);
}
cout<<n-imax<<endl;
}
return 0;
}