Jzoj 模拟算法部分题目(共7题)

1058: 【基础】合唱队形

#include <bits/stdc++.h>
using namespace std;
int n, a[100], mid, j, ans[100];
int main()
{
	scanf("%d", &n);
	for(int i=1; i<=n; i++){
		scanf("%d", &a[i]);
	}
	for(int i=1; i<=n; i++){
		for(int j=i+1; j<=n; j++){
			//从大到小排序 
			if(a[i]<a[j]){
				swap(a[i], a[j]);
			}	
		}
	}
	//最中间位置放最高的同学 
	mid=(n+1)/2;
	ans[mid]=a[1];
	//处理右手边,下标i递减1 
	for(int i=mid-1,j=3; i>=1; i--,j+=2){
		ans[i]=a[j];
	}
	//处理左手边,下标i递增1 
	for(int i=mid+1, j=2; i<=n; i++,j+=2){
		ans[i]=a[j];
	}
	for(int i=1; i<=n; i++){
		printf("%d ", ans[i]);
	}
	return 0;
}

1141: 【基础】喝醉的狱卒

时间超限,得分75%

#include <bits/stdc++.h>
using namespace std;
bool a[100001];	//0表示门锁着,1表示开着 
int n, ans;
int main()
{
	scanf("%d", &n);
	for(int i=1; i<=n; ++i){	//第几轮 
		for(int j=1; j<=n; ++j){//监狱的门 
			if(j%i==0){
				a[j]^=1; 
//				if(a[j]==1){
//					a[j]=0;
//				} 
//				else if(a[j]==0){
//					a[j]=1;
//				}
			}
		}
	}
	for(int i=1; i<=n; ++i){
		if(a[i]==1){
			ans++;
		}
	}
	printf("%d", ans);
	return 0;
}

方法1:成功AC,得分100%

#include <bits/stdc++.h>
using namespace std;
bool a[100001];	//0表示门锁着,1表示开着 
int n, ans;
int main()
{
	scanf("%d", &n);
	for(int i=1; i<=n; ++i){	//第几轮 
		for(int j=i; j<=n; j+=i){//监狱的门 
			a[j]^=1; 
//			if(j%i==0){
//				a[j]^=1; 
//				if(a[j]==1){
//					a[j]=0;
//				} 
//				else if(a[j]==0){
//					a[j]=1;
//				}
//			}
		}
	}
	for(int i=1; i<=n; ++i){
		if(a[i]==1){
			ans++;
		}
	}
	printf("%d", ans);
	return 0;
}

方法2:成功AC,得分100%

#include <bits/stdc++.h>
using namespace std;
int n, ans;
int main()
{
	scanf("%d", &n);
	ans=sqrt(n);
	printf("%d", ans);
	return 0;
}

1748: 【NOIP04普及组】花生采摘

#include <bits/stdc++.h>
using namespace std;
int m, n, k, a[25][25], cnt=1, tot, cur=1, t, ans;
int beforex, beforey, curx, cury;
struct peanut{
	int row, column, num;
}asd[410];
//根据花生数量从大到小排序 
bool cmp(peanut x, peanut y)
{
	return x.num>y.num;
}
int main()
{
	scanf("%d %d %d", &m, &n, &k);
	for(int i=1; i<=m; ++i){
		for(int j=1; j<=n; ++j){
			scanf("%d", &a[i][j]);
			//计算有花生的株数 
			if(a[i][j]){
				tot++;
			}
			asd[cnt].row=i;
			asd[cnt].column=j;
			asd[cnt].num=a[i][j];
			cnt++; 
		}
	}
	cnt--;
	sort(asd+1, asd+cnt+1, cmp);
	//有时间并且有花生 
	while(k && cur<=tot){
		//计算到达cur所花的时间t 
		curx=asd[cur].row;
		cury=asd[cur].column;
		if(cur!=1){
			beforex=asd[cur-1].row;
			beforey=asd[cur-1].column;
//			t=min(beforex+curx, abs(beforex-curx)+abs(beforey-cury))+1;
			t=abs(beforex-curx)+abs(beforey-cury)+1;
		}
		else{
			t=curx+1;
		}
		//如果小于等于k,则采摘
		if(t<=k-curx){	//要求采摘完必须回到路边, 所以需要预留 curx 的时间 
			//采摘了第cur株之后, k减, cur加
//			cout<< k << " " << t << " " << asd[cur].num<<endl;
			ans+=asd[cur].num;
			k-=t;
			cur++;
		}
		else{	//如果到达cur的时间大于k,则无法采摘,退出循环 
			break;
		}
	} 
	//输出答案 
	printf("%d", ans);
	return 0;
}

1149: 【基础】奇数阶幻方

#include <bits/stdc++.h>
using namespace std;
int n, hang, lie, a[40][40];
int print()
{
	for(int i=1; i<=n; i++){
		for(int j=1; j<=n; j++){
			cout << setw(4) << a[i][j];
		}
		cout << endl;
	} 
}
int main()
{
	cin >> n;
	hang=1;
	lie=(n+1)/2;
	a[hang][lie]=1;
	
	for(int i=2; i<=n*n; i++){
		if(hang==1 && lie!=n){
			hang=n;
			lie++;
			a[hang][lie]=i;
		}
		else if(hang!=1 && lie==n){
			hang--;
			lie=1;
			a[hang][lie]=i;
		}
		else if(hang==1 && lie==n){
			hang++;
			a[hang][lie]=i;
		}
		else if(hang!=1 && lie!=n && a[hang-1][lie+1]==0){
			hang--;
			lie++;
			a[hang][lie]=i;
		}
		else if(hang!=1 && lie!=n && a[hang-1][lie+1]!=0){
			hang++;
			a[hang][lie]=i;
		}
	}
	print();
	return 0;	
} 

//暴搜, 还没AC

#include <bits/stdc++.h>
using namespace std;
int n, a[20][20], Max, ans, cnt;
bool vis[400], row[20][20], column[20][20], diagonal1[20], diagonal2[20];
//安排好了x行y列 
bool ok(int x, int y, int num)
{
	a[x][y]=num;
	int sum=0;
	for(int i=1; i<=x-1; ++i){
		sum=0;
		for(int j=1; j<=n; ++j){
			sum+=a[i][j];
		}
		if(sum>ans){
			return false;
		}
	}
	sum=0;
	for(int i=1; i<=y; ++i){
		sum+=a[x][i];
		if(sum>ans){
			return false;
		}
	}
	
	sum=0;
	for(int i=1; i<=min(x, y)-1; ++i){
		sum+=a[i][i];
		if(sum>ans){
			return false;
		}
	}
	return true;
}
bool check()
{
	int sum;
	for(int i=1; i<=n; ++i){
		sum=0;
		for(int j=1; j<=n; ++j){
			sum+=a[i][j];
		}
		if(sum!=ans){
			return false;
		}
	}
	
	for(int i=1; i<=n; ++i){
		sum=0;
		for(int j=1; j<=n; ++j){
			sum+=a[j][i];
		}
		if(sum!=ans){
			return false;
		}
	}
	
	sum=0;
	for(int i=1; i<=n; ++i){
		sum+=a[i][i];
	}
	if(sum!=ans){
		return false;
	}
	
	sum=0;
	for(int i=1; i<=n; ++i){
		sum+=a[i][n-i+1];
	}
	if(sum!=ans){
		return false;
	}
	return true;
}
//准备安排第x行, 第y列的数字 
void dfs(int x, int y)
{
	if(x==n+1 && check()){
		cnt++;
		for(int i=1; i<=n; ++i){
			for(int j=1; j<=n; ++j){
				printf("%4d", a[i][j]);
			}
			printf("\n");
		}
		printf("\n\n");
		return;
	}
	if(y==n+1){
		dfs(x+1, 1);
	}
	else{
		for(int i=1; i<=Max; ++i){
			if(!vis[i] && ok(x, y, i)){
				vis[i]=true;
				a[x][y]=i;
				dfs(x, y+1);
				vis[i]=false; 
			}
		}
	}
}
int main()
{
	scanf("%d", &n);
	Max=n*n;
	ans=n*(Max+1)/2;
	dfs(1, 1);
//	printf("%d", cnt);
	return 0;
}

1541: 【USACO】iCow播放器

#include <bits/stdc++.h>
using namespace std;
int n, t, r[1010], asd, id;
int main()
{
	scanf("%d %d", &n, &t);
	for(int i=1; i<=n; ++i){
		scanf("%d", &r[i]);
	}
	for(int i=1; i<=t; ++i){
		asd=-10;	//权值擂主 
		id=0;
		for(int i=1; i<=n; ++i){
			if(r[i]>asd){
				asd=r[i];
				id=i;
			}
		}
		//选出要播放的曲子id
		printf("%d\n", id);
		asd/=n-1;		//asd表示平均分的 
		for(int i=1; i<=n; ++i){
			if(i!=id){	//跳过它本身 
				r[i]+=asd;
			}
		}
		if(r[id]%(n-1)){	//跳过它本身
			asd=r[id]%(n-1);	//asd表示余数 
			for(int i=1; asd && i<=n; ++i){		//没分完 
				if(i!=id){
					r[i]++;
					asd--; 
				}
			}
		}
		r[id]=0;	//自己权值清零 
	}
	return 0;
}

1521: 【USACO】作弊的发牌者

约瑟夫问题变形,好题

#include <bits/stdc++.h>
using namespace std;
int n, k, p, ans[100010], id, cnt, asd;
queue<int> q;
int main()
{
	scanf("%d %d %d", &n, &k, &p);	//小伙伴数, 牌数, 切牌数 
	for(int i=1; i<=k; ++i){
		q.push(i); 
	}
	while(!q.empty()){
		id++;	//准备给第id个人发牌 
		if(id==n){		//轮到给给贝茜发牌了 
			id=0;
			cnt++;
			ans[cnt]=q.front();
			if(cnt==k/n){
				break;
			} 
		}
		q.pop();	//发牌 
		//切牌 
		for(int i=1; i<=p; ++i){
			asd=q.front();
			q.push(asd);
			q.pop();
		}
	} 
	sort(ans+1, ans+cnt+1);
	for(int i=1; i<=cnt; ++i){
		printf("%d\n", ans[i]);
	}
	return 0;
}

1497: 【USACO】越野跑

#include <bits/stdc++.h>
using namespace std;
int m, t, u, f, d, ans, tim;
char asd;
int main()
{
	//独自进山不得超过m秒, t段路, 上坡时间, 平地时间, 下坡时间 
	scanf("%d %d %d %d %d", &m, &t, &u, &f, &d);
	for(int i=1; i<=t; ++i){
        //使用scanf("%c", &asd); 会把换行读进去,可以在scanf前面加一个getchar();
		cin >> asd; 
		if(asd=='u' || asd=='d'){
			tim=u+d;	//来回 
		}
		else if(asd=='f'){
			tim=2*f;	//来回翻倍 
		}
		if(m>=tim){		//如果时间够 
			ans++;		//答案++ 
			m-=tim;		//剩下的时间 
		}
		else{
			break;		
		}
	}
	printf("%d", ans); 
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ypeijasd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值