PAT之水题:逻辑题、数学问题(素数、多项式、分数、大整数、进制转换)

数学问题总结笔记:进制转换


1 逻辑题

  • 数组+逻辑

1008(20:数组)

(1)题目
电梯(数组)

(2)代码

#include<cstdio>

using namespace std;

const int N=110;

int main(){
   
    int a[N];
    int n;
    scanf("%d", &n);
    for(int i=1; i<=n; i++){
   
        scanf("%d", &a[i]);
    }
    int total=0;
    a[0] = 0;
    for(int i=1; i<=n; i++){
   
        if(a[i] > a[i-1]){
   
            total = total +  (a[i]-a[i-1])*6;
        }else{
   
            total = total + (a[i-1]-a[i])*4;
        }
        total += 5;
    }
    printf("%d", total);
    return 0;
}

1017(25:时间序列模拟 + 优先级队列)

(1)题目
时间序列模拟 + 优先级队列,多个窗口排队办业务

(2)代码

#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>

using namespace std;

typedef struct Node{
   
	int come;
	int process;
	int out;
}Node;

vector<Node> vect;
int endTime = 17*3600+1;

bool cmp1( Node no1, Node no2){
   
	return no1.come < no2.come;
}

struct cmp2{
   
	bool operator()(const Node &no1, const Node &no2){
   
		return no1.out > no2.out;
	}
};


int main(){
   
	//freopen("in.txt", "r",stdin);

	int n, k;
	scanf("%d%d", &n, &k);
	Node node;
	for(int i=0; i<n; i++){
   
		int hh,mm,ss,p;
		scanf("%d:%d:%d%d", &hh, &mm, &ss, &p);
		int t = hh*3600+mm*60+ss;
		if(t < endTime){
   
			node.come = t;
			node.process = p*60;
			vect.push_back(node);
		}
	}
	//
	sort(vect.begin(), vect.end(), cmp1);
	priority_queue<Node, vector<Node>, cmp2> pq;
	int wait=0;
	int tempTime=8*3600;
	if(vect[0].come <= tempTime){
   		//等待
		vect[0].out = tempTime+vect[0].process;
		wait += (tempTime-vect[0].come);
	}else{
   		//不用等
		vect[0].out = vect[0].come+vect[0].process;
	}
	pq.push(vect[0]);
	int id=1;
	while(!pq.empty() && id<vect.size()){
   
		if(pq.size()<k){
   		//未满,进
			if(vect[id].come <= tempTime){
   		//等待
				vect[id].out = tempTime+vect[id].process;
				wait += (tempTime-vect[id].come);
			}else{
   	//不用等
				vect[id].out = vect[id].come+vect[id].process;
			}
			pq.push(vect[id]);
			id++;
		}else{
   		//满了,出
			Node f = pq.top();
			tempTime = f.out;
			pq.pop();
		}
	}
	printf("%.1f", (double)wait/(60*vect.size()));

	//fclose(stdin);
	return 0;
}

(3)小结

  • 以秒为单位,X:Y:Z时间点的秒数为:X*3600+Y*60+Z(以00:00:00为基准)
  • STL:priority_queue
    初始化
priority_queue<int> pq;	//大根堆
priority_queue<int, vector<int>, greater<int> > pq;  //小根堆
priority_queue<Node, vector<Node>, cmp> pq;  

1031(20:数学规律+图形输出)

(1)题目
数学规律+图形输出,字符串U形打印

(2)代码

#include<cstdio>
#include<string>
#include<iostream>

using namespace std;

int main(){
   
	//freopen("in.txt", "r",stdin);

	string s;
	cin>>s;
	int n = s.length();
	int k = (n+2)/3;
	int n2 = n+2-2*k;
	for(int i=0; i<k-1; i++){
   
		printf("%c", s[i]);
		for(int j=0; j<n2-2; j++){
   
			printf(" ");
		}
		printf("%c\n", s[n-i-1]);
	}
	//最下一行
	for(int i=0; i<n2; i++){
   
		printf("%c", s[i+k-1]);
	}

	//fclose(stdin);
	return 0;
}

(3)小结

  • 数学规律:尽量手写化简,最简(一个表达式)

化简后的正确代码:

int k = (n+2)/3;
int n2 = n+2-2*k;

未化简的错误代码:

int k=-1, n2;
	int max_k = -1;
	for(int i=3; i<=n; i++){
   
		if((n+2-i)%2==0){
   
			k = (n+2-i)/2;
		}
		if(k>max_k && k<=i){
   
			max_k = k;
		}
	}

	k = max_k;
	n2 = n+2-2*k;
  • 图形打印,先存到二维数组里,再printf

1042(20:模拟)

(1)题目
模拟,洗牌

(2)代码

#include<cstdio>
#include<string>
#include<iostream>
#include<sstream>
#include<algorithm>

using namespace std;

string str[55];
string tempStr[55];

int main(){
   
	//freopen("in.txt", "r",stdin);

	stringstream ss;
	string s[14];
	for(int i=1; i<=13; i++){
   
		ss<<i;
		s[i] = ss.str();
		ss.clear();
		ss.str("");
	}
	for(int i=1; i<=13; i++){
   
		str[i] = "S"+s[i];
		str[i+13] = "H"+s[i];
		str[i+26] = "C"+s[i];
		str[i+39] =  "D"+s[i];
	}
	str[53] = "J1";
	str[54] = "J2";
	for(int i=1; i<=54; i++){
   
		tempStr[i] = str[i];
	}
	int n;
	scanf("%d", &n);
	int arr[55];
	for(int i=1; i<=54; i++){
   
		scanf("%d", &arr[i]);
	}
	for(int i=0; i<n; i++){
   
		for(int j=1; j<=54; j++){
   
			int id = arr[j];
			str[id] = tempStr[j];
		}
		for(int i=1; i<=54; i++){
   
			tempStr[i] = str[i];
		}
	}
	for(int i=1; i<=54; i++){
   
		if(i!=1) printf(" ");
		printf("%s", str[i].c_str());
	}

	//fclose(stdin);
	return 0;
}

(3)小结

  • stringstream ss,多次使用 清空操作:
ss.str("");
ss.clear();
  • 看清题目,不是交换a和b
    当例子输出的答案错误,一定要手动模拟例子,看是否理解了题目意思
  • 最后直接输出int和string的对应关系,不用存string
    char c[6] = {
   "SHCDJ"};
    for(int i = 1; i < 55; i++) {
   
        end[i] = end[i] - 1;
        printf("%c%d", c[end[i]/13], end[i]%13+1);
        if(i != 54) printf(" ");
    }

1046(20:模拟 + 超时(设置辅助数组))

(1)题目
模拟 + 超时(设置辅助数组),环上两点最短距离

(2)代码

#include<cstdio>
#include<algorithm>

using namespace std;

const int N = 100000+10;

int arr[N];
int dist[N];	//dist[i]为1到i+1的距离和

int main(){
   
	//freopen("in.txt", "r",stdin);

	int n;
	scanf("%d", &n);
	int sum=0;
	dist[0] = 0;
	for(int i=1; i<=n; i++){
   
		scanf("%d", &arr[i]);
		sum += arr[i];
		dist[i] = sum;
	}
	int m;
	scanf("%d", &m);
	for(int i=0; i<m; i++){
   
		int a,b;
		scanf("%d%d", &a, &b);
		int c,d;
		c = min(a,b);
		d = max(a,b);
		//
		printf("%d\n", min(dist[d-1]-dist[c-1], sum-(dist[d-1]-dist[c-1])));
	}

	//fclose(stdin);
	return 0;
}

(3)小结

  • 以下超时,外层必须为10^4,故里层必须为O(1)
for(int i=0; i<m; i++){
     //10^4
	int a,b;
	scanf("%d%d", &a, &b);
	int c,d;
	c = min(a,b);
	d = max(a,b);
	int dist=0;
	for(int j=c;j<d;j++){
   	//10^5
		dist += arr[j];
	}
	printf("%d\n", min(dist, sum-dist));
}

新设一个辅助数组,用空间换时间

int dist[N];	//dist[i]为1到i+1的距离和

1065(20:64位加法判断溢出(A+B 大于或小于 C))

(1)题目
64位加法判断溢出(A+B 大于或小于 C)

(2)代码

#include<cstdio>

using namespace std;

int main(){
   
	//freopen("in.txt", "r",stdin);

	int n;
	scanf("%d", &n);
	long long a,b,c,sum;
	for(int i=1; i<=n; i++){
   
		scanf("%lld%lld%lld", &a, &b, &c);
		sum = a+b;
		//
		if(a>0 && b>0 && sum<0){
   
			printf("Case #%d: true\n", i);
		}else if<
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值