总目录详见https://blog.csdn.net/mrcrack/article/details/84471041
做题原则,找不到测评地址的题不做。2018-11-28
重走长征路---OI每周刷题记录---9月29日 2013
本周共计20题
测评地址:
bfs
1.细胞问题 //在线测评地址https://www.luogu.org/problemnew/show/P1451
2.Knight Moves //在线测评地址https://vjudge.net/problem/POJ-1915
dfs
3.特殊的质数肋骨 //在线测评地址https://www.luogu.org/problemnew/show/P1218
高精度
阶乘统计
4.阶乘统计 //在线测评地址http://codevs.cn/problem/2156/
5.阶乘末尾的零 //在线测评地址http://codevs.cn/problem/2860/
6.阶乘问题 //在线测评地址https://www.luogu.org/problemnew/show/P1134
7.计算n!的值 //在线测评地址https://www.luogu.org/problemnew/show/P1009
贪心
8.装箱问题 //在线测评地址https://www.luogu.org/problemnew/show/P1049
dp
数字三角形2-4
9.数字三角形2 //在线测评地址http://codevs.cn/problem/2189/
10.数字三角形3 //在线测评地址http://codevs.cn/problem/2193/
11.数字三角形4 //在线测评地址http://codevs.cn/problem/2198/
12.最长不下降子序列 //在线测评地址http://codevs.cn/problem/1576/
13.最小中间和 //在线测评网站http://codevs.cn/problem/1382/
14.导弹问题 //在线测评地址https://www.luogu.org/problemnew/show/P1020
15.均分纸牌 //在线测评地址https://www.luogu.org/problemnew/show/P1031
16.机器工厂 //在线测评地址https://www.luogu.org/problemnew/show/P1376
17.机器分配 //在线测评地址https://www.luogu.org/problemnew/show/P2066
dfs
18.素数环 //在线测评地址https://vjudge.net/problem/HDU-1016
模拟
19.黑色星期五 //在线测评地址https://www.luogu.org/problemnew/show/P1202
20.单数?双数? //在线测评地址http://codevs.cn/problem/2163/
题解:
bfs
1.细胞问题
//P1451 求细胞数量
//在线测评地址https://www.luogu.org/problemnew/show/P1451
//每bfs一次,算一个细胞,同时把遇到的非0值置0
//算法的时间复杂度,若测试数据整个为1个细胞,100*100*(100)=10^6
//若测试数据整个为0个细胞,100*100=10^4
//样例通过,提交AC。2018-12-10
#include
#include
char s[110][110];
int next[][2]={{-1,0},{1,0},{0,-1},{0,1}};//上下左右
int vis[110][110],m,n;//突然想到vis[][]还可以有二维形式,开窍了。
struct Point{
int x,y;
}q[12000],p;
void bfs(int x,int y){
int h,t,nx,ny,i;
h=t=1;
q[t].x=x,q[t].y=y,vis[x][y]=1,s[x][y]='0',t++;
while(h
for(i=0;i<4;i++){
nx=p.x+next[i][0];
ny=p.y+next[i][1];
if(0<=nx&&nx
q[t].x=nx,q[t].y=ny,t++;
}
}
h++;
}
}
int main(){
int i,j,cnt=0;
memset(vis,0,sizeof(vis));
scanf("%d%d",&m,&n);
for(i=0;i
for(i=0;i
cnt++;
bfs(i,j);
}
printf("%d\n",cnt);
return 0;
}
2.Knight Moves
//Knight Moves POJ - 1915
//在线测评地址https://vjudge.net/problem/POJ-1915
//借助 题图,样例,还是弄懂了该题。一个单词都没查
//写代码的过程有些失误,但还是通过静态检查找到了问题。
//q[t].s=s+1,t++;//此处写成 t++,q[t].s=s+1;
//样例通过,提交Runtime Error。
//仔细看了看,大意了, q[100000];//此处写成 q[10000]
//修改,提交AC。2018-12-10 20:23
#include
#include
int next[][2]={{-1,-2},{-2,-1},{-2,1},{-1,2},{1,-2},{2,-1},{2,1},{1,2}};
int vis[310][310],n;
struct Point{
int r,c,s;
}q[100000];//此处写成 q[10000]
void bfs(int sr,int sc,int er,int ec){
int h,t,r,c,s,i,nr,nc;
h=t=1;
q[t].r=sr,q[t].c=sc,q[t].s=0,t++,vis[sr][sc]=1;
while(h
if(r==er&&c==ec){
printf("%d\n",s);
return;
}
for(i=0;i<8;i++){
nr=r+next[i][0],nc=c+next[i][1];
if(0<=nr&&nr
}
}
h++;
}
}
int main(){
int t,sr,sc,er,ec;
scanf("%d",&t);
while(t--){
memset(vis,0,sizeof(vis));
scanf("%d",&n);
scanf("%d%d%d%d",&sr,&sc,&er,&ec);
bfs(sr,sc,er,ec);
}
return 0;
}
dfs
3.特殊的质数肋骨
//P1218 [USACO1.5]特殊的质数肋骨 Superprime Rib
//在线测评地址https://www.luogu.org/problemnew/show/P1218
//一开始想用质数筛,但一看99999999,即10^9,O(n)明显超时
//还是用深搜。
//原以为会挺慢,测试下来,速度惊人。样例通过,提交AC。2018-12-12
//该题还有一个办法,打表。
#include
#include
int n,a[15];
int isPrime(int x){//质数 返回1,非质数返回 0
int i;
if(x==1)return 0;
if(x==2)return 1;
for(i=2;i*i<=x;i++)
if(x%i==0)return 0;
return 1;
}
void dfs(int step){
int i,k,ans;
if(step==n+1){
ans=0;
for(k=1;k<=n;k++)//此处写成 for(k=1;k<=n;i++) 真是昏到家了。
ans*=10,ans+=a[k];
if(isPrime(ans))printf("%d\n",ans);
return ;
}
for(i=1;i<=9;i++){
ans=0,a[step]=i;//此处写成a[k]=i//漏了此句a[k]=i
for(k=1;k<=step;k++)
ans*=10,ans+=a[k];
if(isPrime(ans))
dfs(step+1);
}
}
int main(){
scanf("%d",&n);
dfs(1);
return 0;
}
高精度
阶乘统计
4.阶乘统计
//2156 阶乘统计
//在线测评地址http://codevs.cn/problem/2156/
//long long 2^63=9223372036854775808
// 20!=2432902008176640000
//故,该题long long不会溢出
//对long long与int混搭,心存疑虑,立马测试,之后解惑。
//样例通过,提交AC。2018-12-10
#include
#define LL long long
int out[20];//输出的数
int main(){
LL ans=1,b;
int n,k,i,len;
scanf("%d%d",&n,&k);
for(i=1;i<=n;i++)
ans*=i;
while(ans%10==0)ans/=10;//去尾部的0
len=0,b=ans;
while(b){
out[len++]=b%10;
b/=10;
}
if(k>=len)printf("%lld",ans);
else
for(i=k-1;i>=0;i--)
printf("%d",out[i]);
return 0;
}
5.阶乘末尾的零
//2860 阶乘末尾的零
//在线测评地址http://codevs.cn/problem/2860/
//思路,统计每个数的因数10,5,2的个数
//每一对2,5对应一个结果0,每一个10对应一个结果0
//注意:1000!有249个零。
//考虑统计用long long
//担心10^8会超时,测试了一下,估计能险过
//提交AC.2018-12-10
#include
#include
#define LL long long
int min(LL a,LL b){
return a }
int main(){
LL cnt_2=0,cnt_5=0,cnt_10=0;
int i,n,m;
scanf("%d",&n);
for(i=1;i<=n;i++){
m=i;
while(m%10==0)m/=10,cnt_10++;
while(m%5==0)m/=5,cnt_5++;
while(m%2==0)m/=2,cnt_2++;
}
printf("%lld\n",cnt_10+min(cnt_2,cnt_5));
return 0;
}
6.阶乘问题
//P1134 阶乘问题
//在线测评地址https://www.luogu.org/problemnew/show/P1134
//思路,统计每个数的因数5,2的个数
//每一个10对应一个结果0若该数是10的整数倍,可直接跳过,不影响结果
//每一对2,5对应一个结果0,
//注意:注意:10,000,000!有2499999个零。
//考虑统计用long long
//担心5*10^7会超时,测试了一下,估计能险过
//提交AC.2018-12-10 对此次算法表示满意,全是自己编的。
#include
#define LL long long
int main(){
LL cnt_2=0,cnt_5=0,i;
int n,m,ans=1;
scanf("%d",&n);
for(i=1;i<=n;i++){
m=i;
if(m%10==0)m/=10;
while(m%5==0)m/=5,cnt_5++;
while(m%2==0)m/=2,cnt_2++;
ans=(ans*m)%10;
}
if(cnt_2>cnt_5)
for(i=1;i<=cnt_2-cnt_5;i++)
ans=(ans*2)%10;
else if(cnt_2
ans=(ans*5)%10;
printf("%d\n",ans);
return 0;
}
7.计算n!的值
//P1009 阶乘之和
//在线测评地址https://www.luogu.org/problemnew/show/P1009
//看完题目,就知道该用,高精度加法+高精度乘法
//用高精度,总感觉挺糟糕的,代码量不小啊
//该开多大的数组呢,先开大的吧,开到int z[2000]
//之后,测试n=50,再将上述数组 缩小范围。
//循环次数,外层循环(1+50)*50/2=1275,内部循环,大约没算一次大约1000,大致感觉不会超时
//先编一个主体程序,再编高精度乘,只有才是高精度加
//编的过程中,记得及时测试,否则,怎么错都不知道。
//该题的优点是,高精度乘 发生在 数字*整数数组,编起来,相对简单些
//为了尽可能的避免,运算过程中int的溢出,准备对f[]采用long long
//突然想到n!=(n-1)!*n应该能省不少时间
//z[i]+=y[i]+x[i];//此处写成z[i]=y[i]+x[i];查了好久 花了30分钟。
//测试了50的答案为31035053229546199656252032972759319953190362094566672920420940313
//maxn 开到 100即可
//测了一下,n=500反应也很快。决定将maxn开到1000
//样例通过,提交AC。2019-1-15 21:13
//翻看了之前,编写的代码,在伯仲之间,各有优缺点。
//详见https://blog.csdn.net/mrcrack/article/details/78473644
//1173 阶乘和
#include
#include
#define maxn 1000
#define LL long long
LL f[maxn],ans[maxn],g[maxn];
void mul(int a,LL *f){
int i;
for(i=1;i<=f[0];i++)f[i]*=a;
for(i=1;i<=f[0];i++){//进位处理
f[i+1]+=f[i]/10;
f[i]%=10;
}
if(0
while(f[i]>=10){
f[i+1]+=f[i]/10;
f[i]%=10;
i++;
}
f[0]=i;
}
}
void add(LL *x,LL *y,LL *z){
int i;
z[0]=y[0]>x[0]?y[0]:x[0];
for(i=1;i<=z[0];i++){
z[i]+=y[i]+x[i];//此处写成z[i]=y[i]+x[i];查了好久
z[i+1]+=z[i]/10;
z[i]%=10;
}
if(z[i])z[0]=i;
}
int main(){
int n,i;
memset(ans,0,sizeof(0));
scanf("%d",&n);
memset(f,0,sizeof(f));
f[0]=1,f[1]=1;
for(i=1;i<=n;i++){
mul(i,f);
memset(g,0,sizeof(g));//漏了此句
add(f,ans,g);
memcpy(ans,g,sizeof(g));
}
for(i=ans[0];i>=1;i--)printf("%lld",ans[i]);
return 0;
}
贪心
8.装箱问题
//P1049 装箱问题
//NOIP 2001 普及组
//在线测评地址https://www.luogu.org/problemnew/show/P1049
//01背包问题,将物品的体积看成体积、价值即可。
//样例通过,提交AC。2018-12-9 15:31
#include
#include
int v[35],f[35][20100];
int max(int a,int b){
return a>b?a:b;
}
int main(){
int m,n,i,j;
memset(f,0,sizeof(f));
scanf("%d%d",&m,&n);
for(i=1;i<=n;i++)
scanf("%d",&v[i]);
for(i=1;i<=n;i++)
for(j=0;j<=m;j++)
if(j
else
f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+v[i]);
printf("%d\n",m-f[n][m]);
return 0;
}
dp
数字三角形2-4
9.数字三角形2
//2189 数字三角形W
//在线测评地址http://codevs.cn/problem/2189/
//没什么好办法,深搜dfs
//担心的是,超时,试试看吧,没有办法的办法
//该题,节点上最大值未告知,不过还是能应付的,a[i][j]%=100;//防止数据计算int溢出 100*25=2500
//样例通过,提交,测试点1,2WA。2019-1-14 20:24
//发现问题,dfs(a[1][1],1,1,1);//此处写成 dfs(0,1,1,1);
//修改,提交AC。2019-1-14 20:35
#include
#include
int n,a[30][30],b,c,sum,ans=0;
int max(int a,int b){
return a>b?a:b;
}
void dfs(int sum,int step,int r,int c){//r行 c列
int i,j;
if(step==n){
ans=max(ans,sum%100);
return ;
}
for(j=0;j<2;j++)
dfs(sum+a[r+1][c+j],step+1,r+1,c+j);
}
int main(){
int i,j;
memset(a,0,sizeof(a));
scanf("%d",&n);
for(i=1;i<=n;i++)
for(j=1;j<=i;j++){
scanf("%d",&a[i][j]);
a[i][j]%=100;//防止数据计算int溢出 100*25=2500
}
dfs(a[1][1],1,1,1);//此处写成 dfs(0,1,1,1);
printf("%d\n",ans);
}
10.数字三角形3
//2193 数字三角形WW
//在线测评地址http://codevs.cn/problem/2193/
//一度想放弃,想看懂 数字三角形2 递推的解答,
//试图用在 该题上,无奈,一时难以看懂,只好回到深搜dfs的老路上。
//在想,在乱搜中,如何过指定的点,遇到非指定点就跳过去,
//一个想法突然冒出来,这不就是剪枝吗,太高兴了,算法有了。2019-1-15 06:08
//该题有个缺点,没说节点的最大值,在考虑int是否溢出
//样例通过,提交AC。2019-1-15 剪枝有些感觉了
#include
#include
#define maxn 30
int n,a[maxn][maxn],ans=-999999999;
int max(int a,int b){
return a>b?a:b;
}
void dfs(int step,int sum,int r,int c){
int j;
if(r==n/2&&c!=n/2)//剪枝
return;
if(step==n){
ans=max(ans,sum);
return ;
}
for(j=0;j<2;j++)
dfs(step+1,sum+a[r+1][c+j],r+1,c+j);
}
int main(){
int i,j;
scanf("%d",&n);
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
scanf("%d",&a[i][j]);//此处写成scanf("%d",&a[i]);,昏招
dfs(1,a[1][1],1,1);
printf("%d\n",ans);
return 0;
}
11.数字三角形4
//2198 数字三角形WWW
//在线测评地址http://codevs.cn/problem/2198/
//有了 剪枝 这个 技能,该题也就有信心了。
//该题的问题是,节点的最大值是多少,没说,存在int可能溢出的情况。
//样例通过,提交AC。2019-1-15 08:39
#include
#include
#define maxn 30
int n,a[maxn][maxn],x,y,ans=-999999999;
int max(int a,int b){
return a>b?a:b;
}
void dfs(int sum,int step,int r,int c){
int j;
if(r==x&&c!=y)return;//剪枝
if(step==n){
ans=max(ans,sum);
return ;
}
for(j=0;j<2;j++)
dfs(sum+a[r+1][c+j],step+1,r+1,c+j);
}
int main(){
int i,j;
memset(a,0,sizeof(a));
scanf("%d",&n);
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
scanf("%d",&a[i][j]);
scanf("%d%d",&x,&y);
dfs(a[1][1],1,1,1);
printf("%d\n",ans);
return 0;
}
12.最长不下降子序列
//最长不下降子序列 此题不好找,无奈找下题替换
//1576 最长严格上升子序列
//在线测评地址http://codevs.cn/problem/1576/
//样例通过,提交AC。2018-12-19
#include
#define maxn 5100
int a[maxn],d[maxn];
int max(int a,int b){
return a>b?a:b;
}
int main(){
int n,i,j,len=-1;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++){
d[i]=1;
for(j=1;j if(a[j]d[i])
d[i]=d[j]+1,len=max(len,d[i]);
}
printf("%d\n",len);
return 0;
}
13.最小中间和
//最小中间和 找不到 在线测评,只好找 基本类似 来替换
//1382 沙子合并
//在线测评网站http://codevs.cn/problem/1382/
//f[i][j] i->j之间的 最小和
//开一个前缀和b[i] 1->i的和
//f[i][i]=0;//此处真是,神来之笔
//最小的中间和的动归,完全是独立想出,高兴。
//样例通过,提交AC。2018-12-21
#include
#include
#define maxn 310
int a[maxn],f[maxn][maxn],b[maxn];
int min(int a,int b){
return a }
int main(){
int i,j,n,k;
scanf("%d",&n);
memset(f,127,sizeof(f)),b[0]=0;
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
f[i][i]=0;//此处真是,神来之笔
b[i]+=b[i-1]+a[i];
}
if(n==1){//特判,省得添堵
printf("%d\n",a[n]);
return 0;
}
for(k=1;k<=n-1;k++)
for(i=1;i<=n;i++)
if(i+k<=n)
for(j=i;j<=i+k;j++)
f[i][i+k]=min(f[i][i+k],f[i][j]+f[j+1][i+k]+b[i+k]-b[i-1]);
printf("%d\n",f[1][n]);
return 0;
}
14.导弹问题
//P1020 导弹拦截
//NOIP 普及组 1999
//在线测评地址https://www.luogu.org/problemnew/show/P1020
//开数组d[]存储递减序列
//二分法,找当前数据放置d[]数组中位置。
//样例通过,提交AC。2018-12-14 22:07
//算法时间复杂度,O(nlogn).
#include
int a[100100],d[100100];
int main(){
int i,k=1,ans1=0,left,right,mid,ans2=0;
while(scanf("%d",&a[k])!=EOF)k++;
d[0]=60000;
for(i=1;i
ans1++,d[ans1]=a[i];//d[]是递减序列
else{
left=0,right=ans1;
while(left+1
if(d[mid]>=a[i])left=mid;//此处写成 if(d[ans1]>=a[i])left=mid;
else right=mid;
}
d[right]=a[i];//目标,让该递减序列,每个位置的值都尽可能大
}
printf("%d\n",ans1);
d[0]=-1;
for(i=1;i
else{
left=0,right=ans2;
while(left+1
if(d[mid] else right=mid;
}
d[right]=a[i];//想清数据存储格式,采用left还是right,自然明白
}
printf("%d\n",ans2);
return 0;
}
//P1020 导弹拦截
//NOIP 普及组 1999
//在线测评地址https://www.luogu.org/problemnew/show/P1020
//最长不上升子序列 导弹个数
//最长上升降子序列 拦截系统套数
//样例通过,提交WA,只通过了测试点1.
//修改if(a[j]d[i])//计算拦截系统,此处写成 if(a[j]<=a[i]&&d[j]+1>d[i])。
//提交,测试点1-10 AC,O(n^2)通过。2018-12-12 17:30
#include
#include
int a[100100],d[100100];
int max(int a,int b){
return a>b?a:b;
}
int main(){
int k=0,i,j,ans1=-1,ans2=-1;
while(scanf("%d",&a[k])!=EOF)k++;
for(i=0;i
for(j=0;j if(a[j]>=a[i]&&d[j]+1>d[i])
d[i]=d[j]+1,ans1=max(ans1,d[i]);
}
for(i=0;i
for(j=0;j if(a[j]d[i])//计算拦截系统,此处写成 if(a[j]<=a[i]&&d[j]+1>d[i])
d[i]=d[j]+1,ans2=max(ans2,d[i]);
}
printf("%d\n%d\n",ans1,ans2);
return 0;
}
15.均分纸牌
//P1031 均分纸牌
//NOIP 2002 提高组
//在线测评地址https://www.luogu.org/problemnew/show/P1031
//纯模拟,由左往右开始填坑。
//很是高兴,一次提交,就AC。没有参考任何其它。2018-12-19
//样例过程如下
9 8 17 6
10 7 17 6
10 10 14 6
10 10 10 10
#include
#define maxn 110
int a[maxn];
int main(){
int n,i,avg=0,cnt=0;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]),avg+=a[i];
avg/=n;
for(i=1;i
a[i+1]+=a[i]-avg,cnt++;//a[i]多移走,少补进
printf("%d\n",cnt);
return 0;
}
16.机器工厂
//P1376 机器工厂
//在线测评地址https://www.luogu.org/problemnew/show/P1376
//吐糟该题,看了半天没看懂,出题人的第一要务,要让人看懂题
//若无能力表述清楚,至少,应将给出的样例解释清楚。
//对样例进行解释
4 5 共4周 每周每台保管费5
88 200 第1周 每台费用88 需200台
89 400 第2周 每台费用89 需400台
97 300 第3周 每台费用97 需300台
91 500 第3周 每台费用91 需500台
该样例数据计算
第1周 每台费用 88 需200 花销88*200
第2周 每台费用 93 89 需400 花销89*400
第3周 每台费用 98 94 97 需300 花销94*300
第4周 每台费用 103 99 102 91 需300 花销91*300
总花销126900
//有了基本算法,在一堆价格中,取最小值,进行计算
//采用O(n)的算法
//总花销,最大值5000*10000=5*10^7 int不会溢出
//样例通过,提交90分,测试点6 WA.
//翻看题解,表示,不服,怎么会用到long long
//反复读题,才发现,每周最多10000台,每台最多花费5000,最多10000周
//那么最大值10000*5000*10000=5*10^11,现在同意用long long了
//long long cost=0;//之前写成 int cost=0;交90分,测试点6 WA.
//修改,提交AC。2019-1-16
//大意失荆州,题目还是要多读,最好还是要动纸笔。
#include
#include
#define maxn 10100
int n,s,a,b;//b该周的费用,a该周之前一周的费用
int min(int a,int b){
return a }
int main(){
int i,y;
long long cost=0;//之前写成 int cost=0;交90分,测试点6 WA.
a=999999999;
scanf("%d%d",&n,&s);
for(i=1;i<=n;i++){
scanf("%d%d",&b,&y);
a=min(a+s,b);
cost+=a*y;
}
printf("%lld\n",cost);
return 0;
}
17.机器分配
//P2066 机器分配
//在线测评地址https://www.luogu.org/problemnew/show/P2066
//在线测评地址http://ybt.ssoier.cn:8088/problem_show.php?pid=1266
//在两个在线测评网址之间切换,总算弄懂了题意。
//解释样例:
//公司1选3台 盈利50
//公司2选3台 盈利50
//公司3选3台 盈利30
//公司1选1台 盈利30 公司2选1台 盈利20 公司3选1台 盈利20 总共盈利 70
//f[i][j] i台机器 被 j个公司选 的最大盈利值
//打印 分公司编号和该分公司获得设备台数。没什么感觉
//那么,将动归的中间过程打印,找规律。
//发现
//f[1][1]=30,f[0][0]=0 i=1 j=1 k=1
//f[2][2]=50,f[1][1]=30 i=2 j=2 k=1
//f[3][3]=70,f[2][2]=50 i=3 j=3 k=1
//找到规律,以递归的方式打印结果。
//样例通过,提交10分,测试点2-10WA。2019-1-15 17:07
//有多组解的情况处理,if(f[i][j]<=f[i-1][j-k]+a[i][k]){//此处写成 if(f[i][j]
//翻看了之前的代码https://blog.csdn.net/mrcrack/article/details/78440134
//发现for(k=0;k<=j;k++)//此处写成for(k=1;k<=j;k++)
//就这一处差别,造成了 20分 与 100分 的差距。2019-1-15 17:16
//觉的又困惑,针对样例,将for(k=0;k<=j;k++)的数据打印如下
f[1][1]=30 f[1][2]=40 f[1][3]=50
f[2][1]=30 f[2][2]=50 f[2][3]=60
f[3][1]=30 f[3][2]=50 f[3][3]=70
//将for(k=1;k<=j;k++)的数据打印如下
f[1][1]=30 f[1][2]=40 f[1][3]=50
f[2][1]=20 f[2][2]=50 f[2][3]=60
f[3][1]=20 f[3][2]=40 f[3][3]=70
//各位看到差别了吗.2019-1-15 17:20
//该题编写,还是比较满意的,除了一处k=0还是k=1是翻看之前的编写记录,其它都是独立编写,且独立改正的。2019-1-15 17:29
#include
#include
int a[15][20],f[15][20],g[15][20];
void print(int x,int y){//选择了x个公司,选择了y件机器
if(x==0)return;
print(x-1,y-g[x][y]);
printf("%d %d\n",x,g[x][y]);
}
int main(){
int n,m,i,j,k;
memset(f,0,sizeof(f));
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&a[i][j]);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
for(k=0;k<=j;k++)//此处写成for(k=1;k<=j;k++)//这是最关键的一行代码
if(f[i][j]<=f[i-1][j-k]+a[i][k]){//此处写成 if(f[i][j]
g[i][j]=k;//选择了x个公司,选择了y件机器 ,此次需加入的机器数量k
}
printf("%d\n",f[n][m]);
print(n,m);
return 0;
}
dfs
18.素数环
//Prime Ring Problem HDU - 1016
//在线测评地址https://vjudge.net/problem/HDU-1016
//回溯+深搜
//要点,头尾两数和为质数
//提交Wrong Answer,发现 k++,printf("\nCase %d:\n",k);//此处写成 k++,printf("\nCase k:\n");
//提交Wrong Answer,估计 格式的 问题,继续修改
//觉得格式修改无误了,提交,竟然出现Presentation Error
//好歹知道现在出现的问题,就是格式问题。
//再读题,发现这么一句Print a blank line after each case.
//继续修改,提交AC。2018-12-12 一度想要求助网络,不过,还是忍住了,独立AC。
//ACM的提交方式,对格式要求真高。
#include
#include
int vis[30],a[30],n,kase=0;
int isPrime(int x){//质数 返回1 非质数 返回0
int i;
if(x==1)return 0;
if(x==2)return 1;
for(i=2;i*i<=x;i++)
if(x%i==0)return 0;
return 1;
}
void dfs(int step){
int i,k;
if(step==n+1){
if(n>=2&&isPrime(a[1]+a[n])){//此处写成 if(isPrime(a[1]+a[n])
printf("%d",a[1]);
for(k=2;k<=n;k++)
printf(" %d",a[k]);
printf("\n");
}
return;
}
for(i=1;i<=n;i++)
if(vis[i]==0&&isPrime(a[step-1]+i)){
vis[i]=1,a[step]=i;
dfs(step+1);
vis[i]=0;
}
}
int main(){
while(scanf("%d",&n)!=EOF){
memset(vis,0,sizeof(vis));
kase++;
printf("Case %d:\n",kase);//此处写成 k++,printf("\nCase k:\n");
a[1]=1,vis[1]=1;
dfs(2);
printf("\n");//少了此句
}
return 0;
}
模拟
19.黑色星期五
//P1202 [USACO1.1]黑色星期五Friday the Thirteenth
//在线测评地址https://www.luogu.org/problemnew/show/P1202
//看了看该题,有点烦,编好该题,对日期的处理应是手到擒来。
//闰年判定函数,
//月天数数组。
//编完一个函数,或功能,测试是必需的。
//思路,算出每个月13号,从1900年开始的天数,再进行星期几的计算。
//样例通过,提交AC。2018-12-9 17:00
#include
#include
int month[]={0,31,28,31,30,31,30,31,31,30,31,30,31};//month[1]表示1月的天数
int week[10];
int run(int year){//闰年返回1,平年返回0
if(year%100==0)return year%400?0:1;//整百年
else return year%4?0:1;//非整百年
}
int main(){
int n,i,j,year,tot=0,day=0;//tot当年开始之前的总天数。 day=0当年开始的总天数
memset(week,0,sizeof(week));//week[1]周一,week[6]周六,week[0]周日
scanf("%d",&n);
for(i=0;i
month[2]=run(year)?29:28;
if(i>0)tot+=(365+run(year-1));
day=tot+13;
for(j=0;j<12;j++){
day+=month[j];
week[day%7]++;
}
}
printf("%d %d",week[6],week[0]);
for(i=1;i<=5;i++)
printf(" %d",week[i]);
return 0;
}
20.单数?双数?
//2163 单数??双数????
//在线测评地址http://codevs.cn/problem/2163/
//该题,数据(1 <= I <= 10^60)看起来挺吓人
//起始用字符串存储,判断最后一位是否奇偶即可
//样例通过,提交AC。2018-12-9 21:18
#include
#include
char s[100];
int main(){
int t,len;
scanf("%d",&t);
while(t--){
scanf("%s",s);
len=strlen(s);
if((s[len-1]-'0')%2)printf("odd\n");
else printf("even\n");
}
return 0;
}
2019-1-16 AC 该周内容