
1.逃避
https://www.luogu.org/problemnew/show/T14561
注意:
1.输入时需要用EOF判断,否则会TLE。
2.用flag判断字符是不是每一句首字母。
3.ASC('a')=97 ASC('A')=65
代码如下:
#include <cstdio>
char s;
int main()
{
bool flag = true;//用flag判断是否是每一句的首字母
while (scanf("%c",&s)!=EOF)//注意输入时要用EOF判断
{
if(s=='.')flag=true;
else if((s>='A'&&s<='Z')||(s>='a'&&s<='z'))
{
if(flag)
{
if(s>='a'&&s<='z')s-=;//'a'97 'A'65
flag=false;
}
else if(s>='A'&&s<='Z')s+=;
}
printf("%c",s);
}
return ;
}
2.可耻
https://www.luogu.org/problemnew/show/T14562
在考试时觉得每次删除数组中的两个数,都要移动大量数据使数组连贯,不太能实现。
个人想到的办法是开成二维数组,用a[i][1]记录数列,a[i][2]记录下一个数的位置。可惜在考试时写炸了。
题解的思路是:
使用链表,再用一个vis数组记录每个数有没有被删,从n到1扫一遍就可以了
代码如下:
#include <cstdio>
int n, p[], l[], r[];
bool vis[];
void shan(int x)
{
vis[x]=;
vis[r[x]]=;
printf("%d %d ",x,r[x]);
r[l[x]]=r[r[x]];
l[r[r[x]]]=l[x];
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&p[i]);
for(int i=;i<=n;i++)
{
l[p[i]]=p[i-];
r[p[i]]=p[i+];
}
for(int i=n;i>=;i--)
if(!vis[i]&&r[i]!=)shan(i);
return ;
}
3.但有用
https://www.luogu.org/problemnew/show/T14563
考试没思路,暴力都想不出。
废话不多说,直接上题解。
根据题目,每行列操作的次数小于3。操作时行与列之间有影响,但列与列,行与行之间没有影响。可以枚举每行的操作,再用贪心计算每列,寻找答案。
参考代码如下:
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,a[][],cnt[],c1,c2,c0,res,ans;
void solve()
{
res=;
for(int i=;i<=m;i++)
{
c0=c2=c1=;
for(int j=;j<=n;j++)
{
if((a[j][i]+cnt[j])%==&&a[j][i]+cnt[j]<=)c0++;
if((a[j][i]+cnt[j]+)%==&&a[j][i]+cnt[j]+<=)c1++;
if((a[j][i]+cnt[j]+)%==&&a[j][i]+cnt[j]+<=)c2++;
}
res+=max(max(c0,c1),c2);
}
ans=max(ans,res);
}
void dfs(int dep)
{
if(dep==n+)
{
solve();
return;
}
for(int i=;i<=;i++)
{
cnt[dep]=i;
dfs(dep+);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
scanf("%d",&a[i][j]);
dfs();
printf("%d\n",ans);
return ;
}