题解
题目自己上洛谷找找吧
传送门
1.笨小猴
一眼水题,AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<queue>
#include<algorithm>
#include<stack>
#include<map>
#include<cmath>
#include<list>
#include<ctime>
int maxn[26],maxx=-9999999,minx=9999999,mao[26];
int cnt;
char s[110];
bool check(int x)
{
if(x==0||x==1) return false;
for(int i=2;i<=sqrt(x);i++)
{
if(x%i==0)
return false;
}
return true;
}
using namespace std;
int main()
{
//freopen("word.in","r",stdin);
//freopen("word.out","w",stdout);
gets(s);
int len=strlen(s);
for(int i=0;i<len;i++)
{
maxn[s[i]-'a']++;
}
for(int i=0;i<26;i++)
{
if(maxn[i]!=0)
{mao[cnt]=maxn[i];cnt++;}
}
sort(mao,mao+cnt);
minx=mao[0];maxx=mao[cnt-1];
if(check(maxx-minx)==true)
{
printf("Lucky Word\n");
printf("%d",maxx-minx);
return 0;
}
else
{
printf("No Answer\n");
printf("0");
return 0;
}
return 0;
}
做法:有点像桶排,简单模拟,原创代码(好像就我一个这样做)。
2.火柴棒等式
也是简单的模拟,AC代码:
//Let's AK IOI!!!
//by lmrttx
#include<bits/stdc++.h>
using namespace std;
int num[10]={6,2,5,5,4,5,6,3,7,6};
int n,sum;
int get_match(int x)
{
int k=0;
for(int i=x;i!=0;i/=10)
k+=num[i%10];
if(x==0)k+=num[0];
return k;
}
int main()
{
scanf("%d",&n);
for(int i=0;i<=1000;i++)
for(int j=0;j<=1000;j++)
if(get_match(i)+get_match(j)+get_match(i+j)+4==n)
sum++;
printf("%d",sum);
return 0;
}
做法:先用数组表示出每个数字所需的火柴棒个数,然后暴力枚举每两个数相加,很好看懂,其中4表示加号和等号所需的4根火柴棒
3.传纸条
一个还可以的DP
四维也能过
附上三维AC代码:
说明:第一维是 步数,两人步数相同(看作两人同时出发,向对方传纸条)
剩下两维就是其中一人的横坐标和另一人的纵坐标
注意:第一维要开两倍大小,要判断路径是否重合
#include<bits/stdc++.h>
using namespace std;
int f[104][52][52],a[52][52],m,n;
int max_mao(int a1,int a2,int a3,int a4)
{
if(a1<a2)a1=a2;
if(a1<a3)a1=a3;
if(a1<a4)a1=a4;
return a1;
}
int main()
{
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
for(int i=1;i<=m+n-1;i++)
for(int j=1;j<=m;j++)
for(int k=1;k<=m;k++)
{
if(i-j<0 || i-k<0)
continue;
f[i][j][k]=max_mao(f[i-1][j][k],f[i-1][j-1][k-1],
f[i-1][j-1][k],f[i-1][j][k-1])+a[j][i-j+1]+a[k][i-k+1];
if(j==k)//判断路径是否重合,重合减一
f[i][j][k]-=a[k][i-k+1];
}
printf("%d",f[m+n-1][m][m]);
return 0;
}
好好想想,挺好理解的
4.双栈排序
这题考二分图+染色
前置知识:二分图+染色
自己去问问度娘
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int INF=99999999;
const int MAXN=1005;
int n,num,color[MAXN],t[MAXN],s[MAXN];
bool flag,e[MAXN][MAXN];
void paint(int x,int c)
{
color[x]=c;
for(int i=1;i<=n;i++)
if(e[x][i])
{
if(color[i]==c)flag=false;
if(!color[i])paint(i,3-c);
}
}
void make()
{
s[n+1]=INF;
for(int i=n;i>=1;i--)
{
s[i]=t[i];
if(s[i+1]<s[i])
s[i]=s[i+1];
}
for(int i=1;i<n;i++)
for(int j=i+1;j<n;j++)
if(t[i]<t[j]&&s[j+1]<t[i])
e[i][j]=e[j][i]=true;
for(int i=1;i<=n;i++)
if(!color[i])
paint(i,1);
}
void work()
{
if(flag==false)
{
printf("0");
return;
}
stack<int> s1,s2;
int now=1;
for(int i=1;i<=n;i++)
{
if(color[i]==1)
{
s1.push(t[i]);
printf("a ");
}
else
{
s2.push(t[i]);
printf("c ");
}
while( (!s1.empty()&&s1.top()==now)
|| (!s2.empty()&&s2.top()==now) )
{
if(!s1.empty()&&s1.top()==now)
{
s1.pop();
now++;
printf("b ");
}
else
{
s2.pop();
now++;
printf("d ");
}
}
}
}
int main()
{
flag=true;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&t[i]);
make();work();
return 0;
}
为什么用二分图呢???
对数字串进行逐次遍历,如果符合 规则 ,就连线,遍历结束后,自然就有了二分图,然后染色,得到 染色表,借助染色表,完成排序
说真的,不好理解
好好想想吧
结语
快要CSP了
我会写些像这种题解的博客
一起加油迎考!!!
谢谢阅读