数学问题总结笔记:进制转换
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<