A:切木棍
B:机器人走迷宫
C:淘金
D:巨人排队
http://39.106.164.46/problem.php?id=1020
思路:
白给题目。
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 35
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n;
int main(){
while(scanf("%d",&n)!=EOF){
if(n%2==1) printf("0\n");
else printf("%d\n",(n/2-1)/2);
}
return 0;
}
http://39.106.164.46/problem.php?id=1021
思路:
dfs模拟机器人的行走命令。
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 15
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,m,vis[MAX][MAX],ans;
char mp[MAX][MAX],command;
int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}};
struct node{
int x,y;
node(int xx,int yy){
x=xx;
y=yy;
}
};
bool judge(int x,int y){
if(x<1||x>n||y<1||y>m) return false;
return true;
}
void dfs(int x,int y,char command){
vis[x][y]=1;
ans++;
int i;
if(command=='L') i=0;
if(command=='R') i=1;
if(command=='U') i=3;
if(command=='D') i=2;
int xx=x+dir[i][0],yy=y+dir[i][1];
if(judge(xx,yy)==false||vis[xx][yy]==1||mp[xx][yy]=='*'){
if(command=='L') {i=3;command='U';}
else if(command=='U') {i=1;command='R';}
else if(command=='R') {i=2;command='D';}
else if(command=='D') {i=0;command='L';}
}
xx=x+dir[i][0],yy=y+dir[i][1];
if(judge(xx,yy)&&vis[xx][yy]==0&&mp[xx][yy]!='*'){
dfs(xx,yy,command);
}
}
int main(){
while(scanf("%d %d",&n,&m)!=EOF){
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++){
scanf("%s",mp[i]+1);
}
int x,y;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(mp[i][j]!='.'&&mp[i][j]!='*'){
x=i,y=j;
command=mp[i][j];
}
}
}
ans=0;
dfs(x,y,command);
printf("%d\n",ans);
}
return 0;
}
http://39.106.164.46/problem.php?id=1022
思路:
动态规划题目,分为两次dp:
第一次对每行的元素进行dp,求出每行可以取得的最大值dp2[i],dp2[i]表示第i行可以得到的最大值;
第二次对所有行进行dp,筛选出最优的所有行
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 205
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,m,mp[MAX][MAX];
int dp1[MAX],dp2[MAX],res[MAX];
int main(){
while(scanf("%d %d",&n,&m)!=EOF){
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%d",&mp[i][j]);
}
}
for(int i=0;i<n;i++){
dp1[0]=mp[i][0];
dp1[1]=max(mp[i][0],mp[i][1]);
for(int j=2;j<m;j++){
dp1[j]=max(dp1[j-1],dp1[j-2]+mp[i][j]);
}
dp2[i]=dp1[m-1];
}
res[0]=dp2[0];
res[1]=max(dp2[0],dp2[1]);
for(int i=2;i<n;i++){
res[i]=max(res[i-1],res[i-2]+dp2[i]);
}
printf("%d\n",res[n-1]);
}
return 0;
}
http://39.106.164.46/problem.php?id=1023
思路:
贪心,即对于每个学生的身高,都在队伍中找大于等于此身高且最小的那名学生,将本学生放在其后面。但O(n2)肯定是会超时的。其实每个队伍的队尾是按照身高增序排列的,我们可以在这里使用二分法降低时间复杂度。
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 100005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,a[MAX],b[MAX];
int main(){
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
int cnt=0;
for(int i=0;i<n;i++){
if(i==0||b[cnt-1]<a[i]) b[cnt++]=a[i];
else{
int pos=lower_bound(b,b+cnt,a[i])-b;
b[pos]=a[i];
}
}
printf("%d\n",cnt);
}
return 0;
}
http://39.106.164.46/problem.php?id=1024
思路:
bfs。因为每次移动的代价是相同的,所以可以将每次到达的坐标看成一个节点,每次可以-1,+1或者*2,也就是可以看成一个三叉树,然后从根节点进行搜索。
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 100005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,k,vis[MAX],dis[MAX];
void bfs(){
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
queue<int> q;
q.push(n);
vis[n]=1;
dis[n]=0;
while(!q.empty()){
int top=q.front();
q.pop();
if(top==k){
printf("%d\n",dis[top]);
break;
}
int tmp=top-1;//坐标后退一步
if(tmp>=0&&vis[tmp]==0){
vis[tmp]=1;
dis[tmp]=dis[top]+1;//深度加1
q.push(tmp);
}
tmp=top+1;//坐标前进一步
if(tmp<=100000&&vis[tmp]==0){
vis[tmp]=1;
dis[tmp]=dis[top]+1;
q.push(tmp);
}
tmp=top*2;
if(tmp<=100000&&vis[tmp]==0){//坐标乘以2
vis[tmp]=1;
dis[tmp]=dis[top]+1;
q.push(tmp);
}
}
}
int main(){
while(scanf("%d %d",&n,&k)!=EOF){
bfs();
}
return 0;
}