洛谷八连测R4

时间:2023-03-09 22:34:33
洛谷八连测R4

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 ;
}