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