链接: link.
判断是否能改造成回文串,直接暴力解决,我们设一个num[]数组存放各字母出现的次数,如果个数为奇数的字母的数量大于一则能不能构成回文串,反之可以。我们还需要按最小字典序输出,采取正序和倒序各遍历一次,每次输出num[i]/2个,如果存在个数为奇数的字母,我们在第一次正序遍历后再输出一个该字母。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string.h>
using namespace std;
char str[1010];
int num[30];
int main()
{
int t;
while(~scanf("%d",&t))
{
while(t--)
{
getchar();
memset(num,0,sizeof(num));
scanf("%s",str);
int len = strlen(str);
for(int i=0; i<len; i++)
{
num[str[i]-'a']++;//统计数量
}
int sum = 0;
for(int i=0; i<26; i++)
{
if(num[i]%2!=0)//找出奇数个字母的数量
sum++;
}
if(sum>1)//大于一则直接输出
{
cout<<"impossible"<<endl;
continue;
}
char ch;
for(int i=0; i<26; i++)//正向遍历
{
if(num[i]&1)
ch = 'a'+i;//存放奇数个数量的字母
if(num[i]!=0)
{
for(int j=0; j<num[i]/2; j++)
{
printf("%c",'a'+i);
}
}
}
if(sum==1)
printf("%c",ch);//第一次循环后输出一次
for(int i=25; i>=0; i--)//反向遍历
{
if(num[i]!=0)
{
for(int j=0; j<num[i]/2; j++)
{
printf("%c",i+'a');
}
}
}
printf("\n");
}
}
return 0;
}
链接: link.
我们设一个标记数组,每当我们输入一组数据时,我们把在这区间中没有标记的格子数量统计下来,并把这些格子标记,这样就避免了重复统计。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string.h>
#include <algorithm>
using namespace std;
int Map[110][110];
int main()
{
int t,n;
cin>>t;
while(t--)
{
cin>>n;
int I,J,K;
int sum = 0;//统计格子数量
memset(Map,0,sizeof(Map));//初始化
for(int i=0; i<n; i++)
{
cin>>I>>J>>K;
for(int k=0; k<=K-1; k++)//给坐标范围是[0,k],则中间格子的数量为0~k-1个
{
for(int j=I; j<=J-1; j++)//同上
{
if(Map[k][j]==0)
{
sum++;
Map[k][j]=1;
}
}
}
}
cout<<sum<<endl;
}
return 0;
}
链接: link.
采取BFS解决
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int n,m;
struct node
{
int x;
int y;
} que[10010];
int flag;
int d[8][2]= {{-1,0},{1,0},{0,-2},{0,2},{-1,-2},{-1,2},{1,-2},{1,2}};//因为字母之间存在空格所以左右移动都是2
void BFS(char Map[55][55],int x,int y)
{
int head = 0;
int tail = 0;
//入队
que[tail].x = x;
que[tail++].y = y;
int x1,y1,i;
while(head!=tail)
{
//出队
x1 = que[head].x;
y1 = que[head++].y;
if(Map[x1][y1]=='e')//找到'e'就输出
{
flag = 1;
printf("Cutie Pie!\n");
break;
}
for(i=0; i<8; i++)
{
if(x1+d[i][0]>=0&&x1+d[i][0]<n&&y1+d[i][1]>=0&&y1+d[i][1]<2*m-1)//注意范围
{
if(Map[x1][y1]=='p')//找到'p',往下看若为'i'就入队
{
if(Map[x1+d[i][0]][y1+d[i][1]]=='i')
{
que[tail].x=x1+d[i][0];
que[tail++].y=y1+d[i][1];
}
}
if(Map[x1][y1]=='i')//找到'i',往下看若为'e'则入队
{
if(Map[x1+d[i][0]][y1+d[i][1]]=='e')
{
que[tail].x=x1+d[i][0];
que[tail++].y=y1+d[i][1];
}
}
}
}
}
}
int main()
{
int t,i,j;
char Map[55][55];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
getchar();
for(i=0; i<n; i++)
gets(Map[i]);
flag = 0;
for(i=0; i<n; i++)
{
for(j=0; j<2*m-1; j++)//注意字母间有空格
{
flag = 0;
if(Map[i][j]=='p')
{
BFS(Map,i,j);
if(flag)
break;
}
}
if(flag)
break;
}
if(flag==0)
printf("Sorry Man\n");
}
return 0;
}
链接: link.
找出一个上升子序列,且相邻元素直接相差1
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using namespace std;
int dp[20010];
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
memset(dp,0,sizeof(dp));
int cnt = 0;
int num;
for(int i=0;i<n;i++)
{
cin>>num;
dp[num] = max(dp[num],dp[num-1]+1);
cnt = max(cnt,dp[num]);
}
cout<<cnt<<endl;
}
return 0;
}