1001 考察点 字符串的处理
#include<iostream>
#include<vector>
#include<cmath>
#include<string>
using namespace std;
int main(){
int x, y;
cin >> x >> y;
string s = to_string(x+y);
for(int i = 0; i < s.size(); i++){
printf("%c", s[i]);
if(s[i]=='-') continue;
int t = s.size()-i-1;
if(t%3==0 && t!=0) printf(",");
}
printf("\n");
}
1002 思路:开个一百的数组,记录每一项的系数。最后数下几个非零项,依次输出
#include<iostream>
#include<vector>
using namespace std;
const int M = 1000+3;
int main(){
vector<double> v(M, 0);
int K;
scanf("%d", &K);
for(int i = 0; i < K; i++){
int x; double y;
scanf("%d %lf", &x, &y);
v[x] += y;
}
int cnt = 0;
scanf("%d", &K);
for(int i = 0; i < K; i++){
int x; double y;
scanf("%d %lf", &x, &y);
v[x] += y;
}
for(int i = M-1; i >= 0; i--)
if(v[i]!=0) cnt++;
printf("%d", cnt);
for(int i = M-1; i >= 0; i--){
if(v[i] !=0 ) printf(" %d %.1f", i, v[i]);
}
printf("\n");
}
1003 Dij那什么求最短路的算法。要新建两个变量保存路径条数和最大重量,更新最短路的时候分为大于和等于两种情况。
#include<iostream>
#include<vector>
#include<limits.h>
using namespace std;
int n, m, c1, c2;
vector<int> w;
vector<vector<int>> dis;
vector<int> visited;
vector<int> cnts;
vector<int> weights;
int main(){
scanf("%d %d %d %d", &n, &m, &c1, &c2);
for(int i = 0; i < n; i++){
int x; scanf("%d", &x);
w.push_back(x);
}
dis.resize(n, vector<int>(n, -1));
for(int i = 0; i < m; i++){
int x, y, d; scanf("%d %d %d", &x, &y, &d);
dis[x][y] = dis[y][x] = d;
}
dis[c1][c1] = 0;
visited.resize(n, 0);
//visited[c1] = 1;
cnts.resize(n, 0); cnts[c1] = 1;
weights.resize(n, 0); weights[c1] = w[c1];
for(int i = 0; i < n; i++){
int M = INT_MAX;
int t = -1;
for(int j = 0; j < n; j++){
if(visited[j]==0 && dis[c1][j]!=-1 && dis[c1][j]<M){
M = dis[c1][j];
t = j;
}
}
visited[t] = 1;
for(int j = 0; j < n; j++){
if(visited[j]==0 && dis[t][j]!=-1){
if(dis[c1][j]==-1 || dis[c1][j]>dis[c1][t]+dis[t][j]){
dis[c1][j] = dis[c1][t]+dis[t][j];
cnts[j] = cnts[t];
weights[j] = weights[t]+w[j];
}
else if(dis[c1][j]==dis[c1][t]+dis[t][j]){
cnts[j] += cnts[t];
weights[j] = max(weights[j], weights[t]+w[j]);
}
}
}
}
printf("%d %d\n", cnts[c2], weights[c2]);
//cout << cnts[c2] << " ;
}
1004 bfs
#include <iostream>
#include <vector>
#include<queue>
#include<unordered_map>
using namespace std;
const int MAX = 100+2;
int N, M;
int main(){
scanf("%d %d", &N, &M);
vector<vector<int>> tree(MAX);
for(int i = 0; i < M; i++){
int id, k;
scanf("%d %d", &id, &k);
for(int j = 0; j < k; j++){
int x; scanf("%d", &x);
tree[id].push_back(x);
}
}
int root = 1;
queue<int> q;
vector<int> cnt(MAX, 0);
unordered_map<int, int> deep;
deep[1] = 0; q.push(1);
int D = 0;
while(!q.empty()){
int t = q.front(); q.pop();
D = deep[t];
if(tree[t].empty()) cnt[deep[t]]++;
for(int i = 0; i < tree[t].size(); i++){
int y = tree[t][i];
deep[y] = deep[t]+1;
q.push(y);
}
}
bool first = true;
for(int i = 0; i <= D; i++)
{
if(first) first = false; else printf(" ");
printf("%d", cnt[i]);
}
printf("\n");
}
1005 注意和直接为零的情况。WA了一个测试点。
#include<iostream>
#include<vector>
using namespace std;
vector<string> v = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
int main(){
string s;
cin >> s;
int n = 0;
for(int i = 0; i < s.size(); i++){
n += s[i]-'0';
}
if(n==0) {
cout << "zero" << endl;
return 0;
}
bool first = true;
vector<string> ans;
while(n>0){
//
ans.push_back(v[n%10]);
n = n/10;
}
for(int i = ans.size()-1; i>=0; i--){
if(first) first = false; else printf(" ");
cout << ans[i];
}
printf("\n");
}
1006 就按题目说的做
#include<iostream>
#include<vector>
using namespace std;
int m;
int main(){
scanf("%d", &m);
vector<string> ids;
//vector<int> arrs, leas;
int A = 1e8, B = 0;
int x = -1, y = -1;
for(int i = 0; i < m; i++){
string s; cin >> s;
ids.push_back(s);
int x1, y1, z1, x2, y2, z2;
scanf("%d:%d:%d %d:%d:%d", &x1, &y1, &z1, &x2, &y2, &z2);
//arrs.push_back(x1*3600+y1*60+z1);
//leas.push_back(x2*3600+y2*60+z2);
int a = x1*3600+y1*60+z1, b = x2*3600+y2*60+z2;
if(a<A) {A = a; x = i;}
if(b>B) {B = b; y = i;}
}
cout << ids[x] << " " << ids[y] << endl;
}
1007 滑动窗口 保持窗口内和大于零,看情况更新答案。注意全负数的情况,还要注意和为零算普通的答案。
#include<iostream>
#include<vector>
using namespace std;
int m;
vector<int> v;
int main(){
scanf("%d", &m);
for(int i = 0; i < m; i++){
int x; scanf("%d", &x);
v.push_back(x);
}
int l = 0, r = 0;
int sum = 0;
int L = -1, R = -1, ans = -1;
while(r < m){
sum += v[r];
if(sum < 0) {
l = r+1;
sum = 0;
}
else if(sum > ans){
ans = sum;
L = l; R = r;
//cout << l << " " << r << " " << sum << endl;
}
r++;
}
if(ans == -1) printf("%d %d %d\n", 0, v[0], v[m-1]);
else printf("%d %d %d\n", ans, v[L], v[R]);
}
1008 题面意思
#include<iostream>
#include<vector>
using namespace std;
int n;
vector<int> v;
int main(){
scanf("%d", &n);
for(int i = 0; i < n; i++){
int x; scanf("%d", &x);
v.push_back(x);
}
int ans = 0;
for(int i = 0; i < n; i++){
if(i==0) ans += v[i]*6;
else {
if(v[i] > v[i-1])
ans += (v[i]-v[i-1])*6;
else
ans += (v[i-1]-v[i])*4;
}
ans += 5;
}
printf("%d\n", ans);
}
1009 和上面那个多项式题目类似。哇照这个进度我一天能不能A十道啊。
#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;
const int M = 2000+5;
int k;
int main(){
unordered_map<int, double> T1, T2;
scanf("%d", &k);
for(int i = 0; i < k; i++){
int x; double y;
scanf("%d %lf", &x, &y);
T1[x] = y;
}
scanf("%d", &k);
for(int i = 0; i < k; i++){
int x; double y;
scanf("%d %lf", &x, &y);
T2[x] = y;
}
vector<double> cos(M, 0);
for(const auto& a:T1){
for(const auto& b:T2){
cos[a.first+b.first] += a.second*b.second;
}
}
int cnt = 0;
for(int i = 0; i < M; i++)
if(cos[i]!=0) cnt++;
printf("%d", cnt);
for(int i = M-1; i >= 0; i--){
if(cos[i]!=0) printf(" %d %.1f", i, cos[i]);
}
printf("\n");
}
1010 救命 WA了两次呜呜呜还没写出来待我看看。错误点1:进制选择没有上限,我自以为地设置为36。看了一圈题解要二分还要处理溢出orz明天再弄吧。但是为了一天A10题我决定苟个下一题。
气死俺了,这道题花了好长时间,考察的知识点主要是进制。1进制转换要把变量统一为long long。2如果不用二分法直接求,测试点7会超时,得24分,其实我觉得无伤大雅。3二分法我写的条件忘了加else,就这个卡了半天。4其实我没太整明白乘法的溢出的,但是就硬记吧。。
(ps:感谢柳大神
#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
using LL = long long;
string n1, n2;
long long tag, radix;
long long num1, num2;
long long convert(string n, long long radix){
long long ans = 0;
for(auto a:n){
LL t = isdigit(a)?(a-'0'):(a-'a'+10);
ans = ans*radix+t;
if(ans < 0) return -1;
}
return ans;
}
long long handle(){
LL l = 2;
for(auto a:n2){
long long x = isdigit(a)?(a-'0'):(a-'a'+10);
l = max(l, x+1);
}
LL r = max(num1, l);
while(l <= r){
LL m = (l+r)/2;
num2 = convert(n2, m);
if(num2<0 || num2 > num1) r = m-1;
else if(num2 == num1) return m;
else if(num2 < num1) l = m+1;
}
return -1;
}
int main(){
cin >> n1 >> n2 >> tag >> radix;
if(tag==2) swap(n1, n2);
num1 = 0; num2 = 0;
num1 = convert(n1, radix);
LL ans = handle();
if(ans==-1) printf("Impossible\n");
else printf("%lld\n", ans);
}
1011
#include<iostream>
#include<vector>
using namespace std;
int main(){
double x;
double ans = 1;
vector<char> v = {'W', 'T', 'L'};
for(int i = 0; i < 3; i++){
x = 0; char t;
for(int j = 0; j < 3; j++){
double c; scanf("%lf", &c);
if(c > x) t = v[j];
x = max(x, c);
}
printf("%c ", t);
ans *= x;
}
ans = (ans*0.65-1)*2;
printf("%.2f\n", ans);
}
1012 救。。。这道题一直3,4测试点段错误,查了好久没看出错在哪orz。咋办呜呜呜。
太迷惑了,,,调试了几下提交了几次也没查出哪里错,原封不动地重新交了一遍通过了???
真见鬼了我靠。就是先把每门功课都排列一次,更新每个人的最佳名次。好像可以结构化但是那种写法我不太熟练,后面的题目可以练一下。
#include<iostream>
#include<vector>
#include<algorithm>
#include<unordered_map>
using namespace std;
const int MAX = 1e6+5;
int n, m;
vector<int> names(MAX, -1);
vector<double> C, M, E, A;
vector<int> Rank;
vector<char> W;
void handle(char c, const vector<double>& v){
vector<int> ids;
for(int i = 0; i < n; i++) ids.push_back(i);
sort(ids.begin(), ids.end(), [&](const int& l,const int& r){
return v[l] > v[r];});
//for(int i = 0; i < v.size(); i++) cout << v[i] << " "; cout << endl;
vector<int> meiko(n, 1);
for(int i = 0; i < n; i++){
//cout << ids[i] << " ";
if(i>0 && v[ids[i]]==v[ids[i-1]]) meiko[i] = meiko[i-1];
else meiko[i] = i+1;
if(Rank[ids[i]] > meiko[i]) {Rank[ids[i]] = meiko[i]; W[ids[i]] = c;}
}
//cout << endl;
}
int main(){
scanf("%d %d", &n, &m);
for(int i = 0; i < n; i++){
int s; double c, m, e;
cin >> s; scanf("%lf %lf %lf", &c, &m, &e);
names[s] = i; C.push_back(c); M.push_back(m); E.push_back(e);
A.push_back((c+m+e)/3);
//cout << c << " " << m << " " << e << " " << endl;
}
Rank.resize(n,n+1);
W.resize(n, 'A');
handle('A', A);
handle('C', C);
handle('M', M);
handle('E', E);
for(int i = 0; i < m; i++){
int s; cin >> s;
if(names[s]==-1) {printf("N/A\n"); continue;}
int id = names[s];
//cout << s <<" ";
printf("%d %c\n", Rank[id], W[id]);
}
}
1013 并查集或者dfs。tips:写并查集是时候用unordered_map记录父节点最后一个测试点超时了。
#include<iostream>
#include<vector>
#include<unordered_map>
#include<unordered_set>
#include<cstring>
using namespace std;
const int M = 1000+5;
int n, m, k;
vector<int> fathers(M, 0);
int find_father(int n){
if(fathers[n]==n){
return n;
}
fathers[n] = find_father(fathers[n]);
return fathers[n];
}
void bind(int x, int y){
int u = find_father(x);
int v = find_father(y);
fathers[u] = v;
}
int main(){
scanf("%d %d %d", &n, &m, &k);
vector<vector<int>> lines;
for(int i = 0; i < m; i++){
int x, y; scanf("%d %d", &x, &y);
lines.push_back({x, y});
}
for(int i = 0; i < k; i++){
int t; scanf("%d", &t);
for(int j = 0; j <= n; j++) fathers[j] = j;
for(int j = 0; j < m; j++){
if(lines[j][0]==t || lines[j][1]==t) continue;
bind(lines[j][0], lines[j][1]);
}
unordered_set<int> cnts;
for(int j = 1; j <= n; j++){
int r = find_father(j);
cnts.insert(r);
}
int ans = cnts.size()-2;
printf("%d\n", ans);
}
}
#include<iostream>
#include<vector>
#include<unordered_map>
#include<unordered_set>
#include<cstring>
using namespace std;
const int M = 1000+5;
int n, m, k, x;
unordered_map<int, vector<int>> mp;
vector<int> flag;
void dfs(int t, int c){
if(t==x || flag[t]!=0) return;
flag[t] = c;
if(mp.count(t)==0) return;
for(int i = 0; i < mp[t].size(); i++){
int x = mp[t][i];
if(t!=x && flag[x]==0) dfs(x, c);
}
}
int main(){
scanf("%d %d %d", &n, &m, &k);
for(int i = 0; i < m; i++){
int x, y; scanf("%d %d", &x, &y);
mp[x].push_back(y);
mp[y].push_back(x);
}
flag.resize(n+1, 0);
for(int i = 0; i < k; i++){
scanf("%d", &x); int cnt = 1;
for(int t = 0; t <= n; t++) flag[t] = 0;
for(int j = 1; j <= n; j++){
if(j!=x && flag[j]==0) dfs(j, cnt++);
}
printf("%d\n", cnt-2);
}
}
1014 这种写结构体的模拟的题我不太会啊。就有点思路,但是捋不清楚。看下柳神的解析。
模拟的题目要选好结构化对象,本题是窗口。窗口的出列时间,结束时间,该窗口中的队列信息。感觉要熟练快速整合这种信息还是得练。顺便,柳姐,yyds。
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
int n, m, k, q;
struct Node{
int poptime, endtime;
queue<int> q;
};
vector<int> costs;
vector<Node*> windows;
vector<int> ans;
int main(){
scanf("%d %d %d %d", &n, &m, &k, &q);
for(int i = 0; i < k; i++){
int x; scanf("%d", &x);
costs.push_back(x);
}
int id = 0;
ans.resize(k, 0);
for(int j = 0; j < m; j++){
for(int i = 0; i < n; i++){
if(id >= k) break;
if(j==0) {
Node *p = new Node();
p->poptime = costs[i]; p->endtime = 0;
windows.push_back(p);
}
if(j!=0) windows[i]->q.push(costs[id]);
windows[i]->endtime += costs[id];
ans[id] = windows[i]->endtime;
id++;
}
}
ans.resize(k, 0);
while(id < k){
int T = 1e9; int t = -1;
for(int i = 0; i < n; i++){
if(windows[i]->poptime < T) {
T = windows[i]->poptime;
t = i;
}
}
windows[t]->poptime += windows[t]->q.front();
windows[t]->q.push(costs[id]);
windows[t]->endtime += costs[id];
ans[id] = windows[t]->endtime;
//cout << id << " " << t << " " << windows[t]->poptime << " " << windows[t]->endtime << endl;
id++;
}
for(int i = 0; i < q; i++){
int x; scanf("%d", &x);
int t = ans[x-1]; int w = t-costs[x-1];
//cout << x << " " << t << " " << w << endl;
if(w>=540) printf("Sorry\n");
else printf("%02d:%02d\n", 8+t/60, t%60);
}
}
1015 进制写法练习,判断质数
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
int n, d;
bool judge(int n){
if(n==0 || n==1) return false;
int x = sqrt(n);
for(int i = 2; i <= x; i++){
if(n%i==0) return false;
}
return true;
}
int main(){
while(scanf("%d", &n) == 1){
if(n<0) break; scanf("%d", &d);
bool ok1 = judge(n);
int n1 = 0;
while(n > 0){
int x = n%d;
n1 = n1*d+x;
n = n/d;
}
bool ok2 = judge(n1);
if(ok1 && ok2) printf("Yes\n");
else printf("No\n");
}
}