P1618 三连击(升级版)
题目地址
https://www.luogu.com.cn/problem/P1618
题目大意
将 1, 2,3…,9 共 9 个数分成三组,分别组成三个三位数,且使这三个三位数的比例是 A:B:C,试求出所有满足条件的三个三位数
解题思路
划水题,唯一需要注意,判定时,i % a == 0才能成比例
#include<bits/stdc++.h>
using namespace std;
int a[30];
int get(int x,int y,int z){
for(int i = 0; i<= 15;i++) a[i] = 0;
a[0] = 1;
int t;
while(x != 0){
t = x % 10;
x /= 10;
if(a[t] == 1) return 0;
else a[t] = 1;
}
while(y != 0){
t = y % 10;
y /= 10;
if(a[t] == 1) return 0;
else a[t] = 1;
}
while(z != 0){
t = z % 10;
z /= 10;
if(a[t] == 1) return 0;
else a[t] = 1;
}
return 1;
}
int main(){
int a,b,c;
int f = 0;
cin >> a >> b >> c;
for(int i = 100;i < 1000;i++){
if(i % a == 0){
int t = i / a;
int x,y,z;
x = i;
y = b * t;
z = c * t;
if(get(x,y,z)){
f = 1;
cout << x << " " << y << " " << z << endl;
}
}
}
if(f == 0){
cout << "No!!!" << endl;
}
return 0;
}
P2084 进制转换
题目地址
https://www.luogu.com.cn/problem/P2084
题目大意
将一个M进制的数N转换成十进制表示的式子
解题思路
水题,模拟即可
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
string s;
cin >> n >> s;
int le = s.length();
int x = le - 1;
int f = 1;
for(int i = 0;i < le;i++){
if(s[i] != '0'){
if(f == 0)
cout << "+";
else f = 0;
cout << s[i] << "*" << n << "^" << x;
}
x--;
}
return 0;
}
P1478 陶陶摘苹果(升级版)
题目地址
https://www.luogu.com.cn/problem/P1478
题目大意
简单排序
解题思路
简单排序。注意题目限制“陶陶想知道在 s<0 之前最多能摘到多少个苹果”
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
int main(){
int n,s;
int a,b;
cin >> n >> s;
cin >> a >> b;
int c = a + b;
int h,hh;
vector<int> v;
for(int i = 0;i < n;i++){
cin >> h >> hh;
if(h <= c){
v.pb(hh);
}
}
sort(v.begin(),v.end());
int all = 0;
for(int i = 0;i < v.size();i++){
s -= v[i];
if(s < 0){
break;
}
all++;
}
cout << all << endl;
return 0;
}
P2637 第一次,第二次,成交!
题目地址
https://www.luogu.com.cn/problem/P2637
题目大意
有n批草,m个农夫,每个农夫出价ai,求能出的每批草料的最低价格,以及老板能赚到的最多的钱
解题思路
水题。但是这里题目有坑,注意仔细读题
#include<bits/stdc++.h>
using namespace std;
int a[1005];
int main(){
int n,m;
cin >> n >> m;
for(int i = 0;i < m;i++) scanf("%d",&a[i]);
sort(a,a+m);
int M = 0;
int T = 0;
for(int i = 0;i < m;i++){
int s = a[i] * (m - i);
if(s > M){
M = s;
T = a[i];
}
}
cout << T << " " << M << endl;
return 0;
}
P1206 [USACO1.2]回文平方数 Palindromic Squares
题目地址
https://www.luogu.com.cn/problem/P1206
题目大意
任意进制转换+回文数判定
解题思路
代码由十进制数转换任意进制、回文串判定构成,可以当作板子
#include<bits/stdc++.h>
using namespace std;
string get(int n,int b){
stack<int> s;
int r = n % b;
n = n / b;
s.push(r);
while(n >= b){
r = n % b;
s.push(r);
n = n / b;
}
if(n != 0)
s.push(n);
string x = "";
while(!s.empty()){
int t = s.top();s.pop();
if(t > 9){
x += t - 10 + 'A';
}else{
x += t - 0 + '0';
}
}
return x;
}
int check(string s){
int le = s.length();
int x;
if(le & 1)
x = (le + 1) / 2;
else
x = le / 2;
for(int i = 0; i < x;i++){
if(s[i] != s[le - 1 - i]){
return 0;
}
}
return 1;
}
int main(){
int b;cin >> b;
for(int i = 1;i <= 300;i++){
int x = i * i;
string s1 = get(i,b);
string s2 = get(x,b);
if(check(s2)){
cout << s1 << " " << s2 << endl;
}
}
return 0;
}
【模板】单源最短路径(弱化版)
题目地址
https://www.luogu.com.cn/problem/P3371
题目大意
spfa
解题思路
静态邻接表存储 + spfa
#include<bits/stdc++.h>
using namespace std;
const long long inf=2147483647;
const int maxn = 10005; //点数
const int maxm = 500005; //边数
int n,m,s,num_edge=0;
int dis[maxn],vis[maxn],head[maxm];
//数据边数m<=500000,邻接矩阵存不下,只能使用静态邻接表存储
struct Edge{
int next,to,dis;
}edge[maxm];
//邻接表建图
void addedge(int from,int to,int dis) {
edge[++num_edge].next = head[from]; //链式存储下一条出边
edge[num_edge].to = to; //当前节点编号
edge[num_edge].dis = dis; //本条边的距离
head[from] = num_edge; //记录下一次的出边情况
}
void spfa(){
queue<int> q; //spfa用队列
for(int i=1; i <= n; i++) {
dis[i] = inf; //带权图初始化
vis[i] = 0; //记录点i是否在队列中,同dijkstra算法中的visited数组
}
q.push(s); dis[s]=0; vis[s]=1; //第一个顶点入队,进行标记
while(!q.empty()){
int u = q.front(); //取出队首
q.pop();
vis[u] = 0; //出队标记
//邻接表遍历
for(int i = head[u]; i; i = edge[i].next){
int v = edge[i].to;
//如果有最短路就更改
if(dis[v] > dis[u] + edge[i].dis){
dis[v] = dis[u] + edge[i].dis;
//未入队则入队
if(vis[v]==0){
vis[v] = 1; //标记入队
q.push(v);
}
}
}
}
}
int main(){
cin>>n>>m>>s;
for(int i=1; i<=m; i++){
int f,g,w;
cin >> f >> g >> w;
addedge(f,g,w); //建图,有向图连一次边就可以了
}
spfa();
for(int i = 1; i <= n; i++)
if(s == i) cout << 0 << " "; //如果是回到自己,直接输出0
else cout << dis[i] <<" "; //否则打印最短距离
return 0;
}