小Ho给自己定了一个宏伟的目标:连续100天每天坚持在hihoCoder上提交一个程序。100天过去了,小Ho查看自己的提交记录发现有N天因为贪玩忘记提交了。于是小Ho软磨硬泡、强忍着小Hi鄙视的眼神从小Hi那里要来M张"补提交卡"。每张"补提交卡"都可以补回一天的提交,将原本没有提交程序的一天变成有提交程序的一天。小Ho想知道通过利用这M张补提交卡,可以使自己的"最长连续提交天数"最多变成多少天。
Input第一行是一个整数T(1 <= T <= 10),代表测试数据的组数。
每个测试数据第一行是2个整数N和M(0 <= N, M <= 100)。第二行包含N个整数a1, a2, ... aN(1 <= a1 < a2 < ... < aN <= 100),表示第a1, a2, ... aN天小Ho没有提交程序。
Output对于每组数据,输出通过使用补提交卡小Ho的最长连续提交天数最多变成多少。
3 5 1 34 77 82 83 84 5 2 10 30 55 56 90 5 10 10 30 55 56 90Sample Output
76 59 100
/*
补提交卡当然是连续用才能得到最长的连续登录天数啊
1.补提交卡数目大于未提交天数的时候直接输出100
2.在其他情况下,用以一个数组储存来储存结果
在进行一个排序就OK了
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int t,n,m;
int a[105];
int b[105];
int cmp(int a,int b)
{
return a>b;
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
if(m>=n)
{
printf("100\n");
continue;
}
int j=0;
for(int i=m;i<n;i++)
{
if(i-m-1<0) b[j++]=a[i]-1;
else b[j++]=a[i]-a[i-m-1]-1;
}
sort(b,b+j,cmp);
printf("%d\n",b[0]);
}
return 0;
}
B - B
HihoCoder - 1558
H国的身份证号码是一个N位的正整数(首位不能是0)。此外,由于防伪需要,一个N位正整数是合法的身份证号码当且仅当每位数字都小于等于K,并且任意相邻两位数字的乘积也小于等于K。
例如对于K=5, 101、211、210等都是合法的号码,而106、123、421等都是非法的号码。
给定一个正整数N以及K,请从小到大输出所有合法的号码。
Input两个整数N和K。
对于80%的数据,1 ≤ N ≤ 6。
对于100%的数据,1 ≤ N ≤ 9,1 ≤ K ≤ 5。
Output按从小到大的顺序输出所有合法的N位号码,每个号码占一行。
2 4Sample Output
10 11 12 13 14 20 21 22 30 31 40 41
/*
参考于帆神的代码,
帆神觉得dfs复杂度太高,就自己写了一个模拟
很强
下面来一起欣赏:
*/
#include<cstdio>
#include<cstring>
int a[100];//模拟数组
int main()
{
memset(a,0,sizeof(a));//初始化
a[1]=1;//但是n位数中的第一位需要时1,因为首位不能是0
int n,k;
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++) printf("%d",a[i]);//首先输出最小的一个
printf("\n");//末尾换行
while(true)
{
a[n]+=1;//末位+1
for(int i=n;i>0;i--)
{
if(a[i]==10)
{
a[i]=0;
a[i-1]+=1;
}
}
for(int i=n;i>0;i--)
{
if(a[i]>k||a[i]*a[i+1]>k||a[i]*a[i-1]>k)
{
for(int j=0;j<11;j++) a[i+j]=0;
a[i-1]+=1;
continue;
}
}
if(a[0]==1) break;//结束的条件,就是首位大于10;
for(int i=1;i<=n;i++) printf("%d",a[i]);
printf("\n");
}
return 0;
}
你的任务是在已知地雷出现位置的情况下,得到各个方块中的数据。
*... .... “*”表示有地雷 .*.. “.”表示无地雷 ....经过处理应得到
*100 2210 1*10 1110
2 3 *** ... 4 4 *... .... .*.. .... 0 0Sample Output
*** 232 *100 2210 1*10 1110
/*
C
广搜类型的题
从*开始向八个方向搜索,
八个位置如果没有*,该位置对应的二维数组的值就加1
WA了两次,第一次是语言选择错误。。。
第二次是最后没有输出第二个换行符
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
const int MAXN=108;
const int MAXM=108;
const int INF=0x3f3f3f3f;
char s[MAXM][MAXN]; //读取字符串
int a[MAXM][MAXN]; //保存数字
int n,m,x,y; //n*m的矩阵 x,y来保存坐标
int main()
{
while(scanf("%d %d",&n,&m)!=EOF)
{
if(m==0&&n==0) break;
memset(a,0,sizeof(a)); //初始化a数组的值都为0
for(int i=0;i<n;i++) scanf("%s",s[i]); //读取每一行的字符
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
if(s[i][j]=='*') //找地雷
{
a[i][j]=INF; //有地雷的话讲该位置的值设为INF
int x=i,y=j; //
for(int dx=-1;dx<=1;dx++) //八个方向,用两个循环可以解决
for(int dy=-1;dy<=1;dy++)
{
int nx=x+dx,ny=y+dy;
if(s[nx][ny]!='*'&&a[nx][ny]!=INF) a[nx][ny]++;
}
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(a[i][j]==INF) printf("*"); //输出的时候需要吧地雷也输出
else printf("%d",a[i][j]);//其他位置输出附近有多少雷
}
printf("\n");
}
printf("\n"); //要记着看清题目,每个测试样例中间有一个空行
}
return 0;
}
D - D
FZU - 2230象棋翻翻棋(暗棋)中双方在4*8的格子中交战,有时候最后会只剩下帅和将。根据暗棋的规则,棋子只能上下左右移动,且相同的级别下,主动移动到地方棋子方将吃掉对方的棋子。将和帅为同一级别。然而胜负在只剩下帅和将的时候已定。
第一行T,表示T组数据。
每组数据共有四行字符串,每行字符串共八个字符
’#’表示空格
’*’表示红方帅
’.’表示黑方将
此时红方先走
每组输入之间没有空行。
每组数据输出一行。若为红方赢输出Red win,否则输出 Black win
1 ######.# #####*## ######## ########Sample Output
Black win
/*
D
博弈论
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
char s[10][10];
int x1,x2,y1,y2;
int t;
int main()
{
scanf("%d",&t);
while(t--)
{
for(int i=0;i<4;i++) scanf("%s",s[i]);
for(int i=0;i<4;i++)
for(int j=0;j<8;j++)
{
if(s[i][j]=='*') {x1=i;y1=j;} //找到红方帅
if(s[i][j]=='.') {x2=i;y2=j;} //找到黑方帅
}
int x=abs(x2-x1); //二者坐标的绝对值
int y=abs(y2-y1);
if(abs(y-x)%2==0) printf("Black win\n");
else printf("Red win\n");
}
return 0;
}
E - E
FZU - 10752 11 9828Sample Output
11 2*2*3*3*3*7*13
/*
E题
将一个正整数分解为若干素数的乘积
*/
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXN= 70000;
int a[MAXN],b[MAXN],tot;
int temp,now,n,k;
int main()
{
scanf("%d",&k);
while(k--)
{
scanf("%d",&n);
now=n;
temp=(int)((double)sqrt(n)+1);
tot=0;
now=n;
for(int i=2;i<=temp;i++)
if(now%i==0)
{
a[++tot]=i;
b[tot]=0;
while(now%i==0)
{
++b[tot];
now/=i;
}
}
if(now!=1)
{
a[++tot]=now;
b[tot]=1;
}
for(int i=1;i<=tot;i++)
if(i==1)
{
printf("%d",a[i]);
for(int j=1;j<b[i];j++)
printf("*%d",a[i]);
}
else
{
for(int j=1;j<=b[i];j++)
printf("*%d",a[i]);
}
printf("\n");
}
return 0;
}
F - F
51Nod - 1289有N条鱼每条鱼的位置及大小均不同,他们沿着X轴游动,有的向左,有的向右。游动的速度是一样的,两条鱼相遇大鱼会吃掉小鱼。从左到右给出每条鱼的大小和游动的方向(0表示向左,1表示向右)。问足够长的时间之后,能剩下多少条鱼?Input第1行:1个数N,表示鱼的数量(1 <= N <= 100000)。
第2 - N + 1行:每行两个数A ii, B ii,中间用空格分隔,分别表示鱼的大小及游动的方向(1 <= A ii<= 10^9,B ii = 0 或 1,0表示向左,1表示向右)。Output输出1个数,表示最终剩下的鱼的数量。Sample Input
5 4 0 3 1 2 0 1 0 5 0Sample Output
2
/*因为开始的那些鱼如果向左游的话,肯定死不了
所以直接保留那些鱼的个数,但是不让它们进栈
因为他们无法与进栈元素发生冲突
只让向右游的鱼进栈
*/
#include<cstdio>
#include<stack>
using namespace std;
int n;
int main()
{
while(~scanf("%d",&n))
{
stack<int> s;
int ans=n;
int x,y;
for(int i=0;i<n;i++)
{
scanf("%d%d",&x,&y);
if(y==1) s.push(x);
else
while(s.size())
{
if(x>s.top()){ans--;s.pop();}
else {ans--;break; }
}
}
printf("%d\n",ans);
}
return 0;
}
G - G
HihoCoder - 1000计算A+B
Input输入含有多组测试样例。
每组测试样例包含两个整型数字:A(1 ≤ A ≤ 100)和 B(1 ≤ B ≤ 100)
对每一组测试,输出 A+B 的结果
Sample Input1 2
3 4
3
7
#include<cstdio>
int main()
{
int a,b;
while(scanf("%d %d",&a,&b)!=EOF)
{
printf("%d\n",a+b);
}
return 0;
}
H - H
HDU - 2120ce_cream的世界是一个富裕的国家,它有许多肥沃的土地。 今天,ice_cream的女王想要获得奖励土地给勤奋的ACM队员。 因此,建立了一些了瞭望塔,并在两座瞭望塔之间建造了墙,以便划分冰雪世界。 但女王最多可以颁发多少给多少名ACMer是一个大问题。 一个围墙土地必须交给一个ACMer,并且没有任何墙在之间,如果你能帮助女王解决这个问题,你将得到一块土地。
Input题目有多组数据,每组数据中,前两个整数N,M(N <= 1000,M <= 10000)代表了了望塔的数量和墙的数量。 守望台编号从0到N-1。 接下来在M行之后,每行包含两个整数A,B意味着A和B之间有一面墙(A和B是不同的)。 按文件结尾终止。
Output输出一个数字,表示最多有多少个ACMer可以得到奖励。
Sample Input8 10
0 1
1 2
1 3
2 4
3 4
0 5
5 6
6 7
3 6
4 7
3
//大佬说这是并查集+判环
#include<cstdio>
#include<cstring>
int pre[1008];
void init(int n)
{
for(int i=0;i<n;i++) pre[i]=i;
}
int find(int x)
{
return x==pre[x]?x:pre[x]=find(pre[x]);
}
bool join(int x,int y)
{
x=find(x);
y=find(y);
if(x==y) return true;//根节点相同说明成环
pre[x]=y;
return false; //否则就返回0
}
int main()
{
int n,m;
while(scanf("%d %d",&n,&m)!=EOF)
{
int a,b;
int ans=0;
init(n);
for(int i=0;i<m;i++)
{
scanf("%d %d",&a,&b);
ans+=join(a,b);//查找一共有几个环
}
printf("%d\n",ans);
}
return 0;
}
I - I
51Nod - 1432魔法学院放暑假了,WC和他的一帮魔友一起去弗尔夫斯基山脉玩。莫伊拉同学突然想划船到对岸找被削的Mercy玩,这里的每一艘船都是同一型号,能承受的重量都是一样的,并且每艘船都可以坐一个或者两个人。WC他们共有n个人,现在我们知道他们每个人的质量,而且每个人体重也不超过船的承重。可惜经费有限,他们必须租尽可能少的船,请问他们最少要租几艘船?
Input第一行包含两个正整数n 和m ,n<=10^4,m<=2*10^9,表示人的数量和船的最大承重。 接下来n行,每行一个正整数,表示每个人的体重。体重不超过m。
Output一行一个整数表示最少需要的独木舟数。Sample Input
3 6 1 2 3Sample Output
2
/*
I题
一个简单的贪心
让重量大的人尽量和重量小的人坐在一个船上
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
int a[1000000];
int cmp(int a,int b)
{
return a>b;
}
int main()
{
while(scanf("%d %d",&n,&m)!=EOF)
{
memset(a,0x3f,sizeof(a));
int sum=0;
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n,cmp); //从大到小排序
int z=n;
for(int i=0;i<z;i++)
{
if(a[i]+a[z-1]<=m)
{
sum++;
a[i]=0;
a[z-1]=0;
z--;
}
else
{
sum++;
a[i]=0;
}
}
printf("%d\n",sum);
}
return 0;
}
J - J
HihoCoder - 1041小Hi和小Ho准备国庆期间去A国旅游。A国的城际交通比较有特色:它共有n座城市(编号1-n);城市之间恰好有n-1条公路相连,形成一个树形公路网。小Hi计划从A国首都(1号城市)出发,自驾遍历所有城市,并且经过每一条公路恰好两次——来回各一次——这样公路两旁的景色都不会错过。
令小Hi苦恼的是他的小伙伴小Ho希望能以某种特定的顺序游历其中m个城市。例如按3-2-5的顺序游历这3座城市。(具体来讲是要求:第一次到达3号城市比第一次到达2号城市早,并且第一次到达2号城市比第一次到达5号城市早)。
小Hi想知道是否有一种自驾顺序满足小Ho的要求。
Input输入第一行是一个整数T(1<=T<=20),代表测试数据的数量。
每组数据第一行是一个整数n(1 <= n <= 100),代表城市数目。
之后n-1行每行两个整数a和b (1 <= a, b <= n),表示ab之间有公路相连。
之后一行包含一个整数m (1 <= m <= n)
最后一行包含m个整数,表示小Ho希望的游历顺序。
OutputYES或者NO,表示是否有一种自驾顺序满足小Ho的要求。
2 7 1 2 1 3 2 4 2 5 3 6 3 7 3 3 7 2 7 1 2 1 3 2 4 2 5 3 6 3 7 3 3 2 7Sample Output
YES NO
传送门:https://blog.csdn.net/u010535824/article/details/40652865
/******************************************************
* File Name: 1041.cpp
* Author: kojimai
* Create Time: 2014年10月31日 星期五 12时43分10秒
******************************************************/
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<bitset>
using namespace std;
#define FFF 105
int a[FFF],first[FFF],e,cnt = 0,num,next[FFF*2],v[FFF*2];
bitset<FFF> shao[FFF];//用bitset来存每个节点的子节点中能到达点的情况
bool vis[FFF*2],ans;
void addedge(int x,int y)
{
v[e] = y;next[e] = first[x];first[x] = e++;
v[e] = x;next[e] = first[y];first[y] = e++;
}
void solve_can(int now,int fa)//处理出now节点的子树中能到达的点
{
shao[now][now] = 1;//首先自身能到达自身位置
for(int k = first[now]; ~k;k = next[k])
{
int val = v[k];
if(val == fa)
continue;
solve_can(val,now);//找出子节点的子树中能到达的点
shao[now] |= shao[val];//子节点能到达的点,当前点也能到,用bitset处理可以直接用或运算比较快捷
}
return;
}
void solve(int now,int fa)
{
if(now == a[cnt])//访问到指定顺序的点,则准备访问下一个点
{
cnt++;
}
if(cnt == num)
{
ans = true;//所有点都访问完了,则说明最后可行
return;
}
while(cnt < num)
{
int tmp = cnt;
for(int k = first[now]; ~k;k = next[k])
{
int val = v[k];
if(val == fa)
continue;
if(shao[val][a[cnt]] && !vis[k])//目标点可达且该条路没有访问过,则向下深搜
{
vis[k] = true;//标记路径已经访问过
solve(val,now);
break;
}
}
if(tmp == cnt)//假如当前节点无法到达指定顺序的点或者路径已访问过不能走则返回父节点继续深搜
break;
}
return;
}
int main()
{
int keng;
scanf("%d",&keng);
while(keng--)
{
ans = false;
int x,y;
memset(first,-1,sizeof(first)); e = 0;
int n;
scanf("%d",&n);
for(int i = 1;i < n;i++)
{
scanf("%d%d",&x,&y);
addedge(x,y);
}
scanf("%d",&num);
for(int i = 0;i < num;i++)
scanf("%d",&a[i]);
for(int i = 1;i <= n;i++)
shao[i].reset();
solve_can(1,-1);//预处理每个点的子树能到达哪些点
memset(vis,false,sizeof(vis));
cnt = 0;//记录按顺序已经访问到第几个点
solve(1,-1);
if(ans)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
K - K
HDU - 2018n=0表示输入数据的结束,不做处理。Output对于每个测试实例,输出在第n年的时候母牛的数量。
每个输出占一行。Sample Input
2 4 5 0Sample Output
2 4 6
/*
K题
是斐波那契数列的变形
a1=1 a2=2 a3=3 a4=4 a5=6=a4+a2;
找到规律 a[n]=a[n-1]+a[n-3]
就很容易做出来了
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[60];
void p()
{
a[0]=1;a[1]=1;a[2]=2;a[3]=3;a[4]=4;a[5]=6;
for(int i=6;i<60;i++)
a[i]=a[i-1]+a[i-3];
}
int main()
{
p();
int n;
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
printf("%d\n",a[n]);
}
return 0;
}