比赛的时候写的心态爆炸 掀桌 其实比完看看还是有不少模板题的QWQ
原题链接
7-2 小明环游宇宙 (5分)
进制转换。借助十进制作为中间变量进行转换。题目说了都是小于10进制的数~基础题。
#include
#include
#include
using namespace std;
int a,b,temp;
char c[1005];
stack<int> s;
int convert_to_10(int a, char* c){
int ans = 0, len = strlen(c);
for(int i = 0; i < len; ++i)
ans = ans * a + c[i] - '0';
return ans;
}
void convert_to_b(int temp, int b){
do{
s.push(temp % b);
}while(temp /= b);
while(s.size()){
printf("%d",s.top());
s.pop();
}
}
int main(){
scanf("%d%d %s",&a,&b,c);
temp = convert_to_10(a,c);
convert_to_b(temp, b);
return 0;
}
放一个通用的(可以>10)的代码:
#include
#include
#include
int convert(int n,char *a){
int len = strlen(a);
int ans = 0;
for(int i = 0;i < len; i++){
if(isdigit(a[i]))
ans = ans * n + a[i] - '0';
else
ans = ans * n + a[i] - 'A' + 10;
}
return ans;
}
void conv(int ans,int b){
char arr[1005];
int cnt = 0,tmp;
while(ans){
tmp = ans % b;
if(tmp >= 10)
arr[cnt++] = tmp - 10 + 'A';
else
arr[cnt++] = tmp + '0';
ans = ans / b;
}
for(int i = cnt - 1; i >= 0; i--)
printf("%c",arr[i]);
}
int main(){
char a[1005];
int n, b, temp;
scanf("%d%d%s",&n,&b,a);
temp = convert(n,a);
conv(temp,b);
return 0;
}
7-3 纸条 (10分)
基础题~strstr(第二个参数才是要查找的子串!)的应用!
用两个指针移动就可以啦 用最简单的方法就好。注意字符串是const char*,不能移动哦~
#include
#include
char target[] = "19260817", str[1000005], *p, *q;
int cnt;
int main(){
scanf("%s",str);
q = str;
while(p = strstr(q,target)){
cnt++;
q = p + 1;
}
printf("%d",cnt);
return 0;
}
7-4 争一 (10分)
我不想再看见这个题了……就因为开这个又没注意细节,后面都没时间了 血亏!
“首先按照得分高低排名,如果有人得分相同,那么最初位置是东的排在南、西、北的前面,南排在西、北前面,西排在北前面。”
#include
#include
using namespace std;
bool judgenorth(int a, int b, int c, int d){
int large = max(max(a,b),c);
//stage 1
if(d + 12000 > large - 4000) return true;
//stage 2
d += 12000;
if((d > a - 12000 && d > b && d > c) || (d > b - 12000 && d > a && d > c) || (d > c - 12000 && d > a && d > b)) return true;
return false;
}
bool judgeeast(int a,int b,int c,int d){
//stage 3
if((a + 8000) >= max(max(b - 2000, c - 2000), d - 4000)) return true;
//stage 4
a += 8000;
if((a >= b - 8000 && a >= c && a >= d) || (a >= c - 8000 && a >= b && a >= d) || (a >= d - 8000 && a >= c && a >= b)) return true;
return false;
}
bool judgesouth(int a,int b,int c,int d){
//stage 3
if((b + 8000) >= max(c - 2000, d - 4000) && (b + 8000) > a - 2000) return true;
//stage 4
b += 8000;
if((b > a - 8000 && b >= c && b >= d) || (b >= c - 8000 && b > a && b >= d) || (b >= d - 8000 && b >= c && b > a)) return true;
return false;
}
bool judgewest(int a,int b,int c,int d){
//stage 3
if((c + 8000) > max(a - 2000, b - 2000) && c + 8000 >= d - 4000) return true;
//stage 4
c += 8000;
if((c > a - 8000 && c > b && c >= d) || (c > b - 8000 && c > a && c >= d) || (c >= d - 8000 && c > b && c > a)) return true;
return false;
}
int main(){
int n,a,b,c,d;
scanf("%d",&n);
for(int i = 1; i <= n; ++i){
scanf("%d%d%d%d",&a,&b,&c,&d);
(judgeeast(a,b,c,d))? printf("1 ") : printf("0 ");
(judgesouth(a,b,c,d))? printf("1 ") : printf("0 ");
(judgewest(a,b,c,d))? printf("1 ") : printf("0 ");
(judgenorth(a,b,c,d))? printf("1 ") : printf("0 ");
printf("\n");
}
return 0;
}
7-5 王者荣耀 (15分)
简单题。根据题意模拟就好~不要被吓到,其实很简单的!
#include
int n,x1,y1;
int main(){
scanf("%d",&n);
for(int i = 1; i <= n; ++i){
scanf("%d%d",&x1,&y1);
if(i <= 3 || ((i - 3) % 4 == 0)){
printf("%d %d %d\n",x1 + 1,y1,3);
}else{
if(i % 4 == 0) printf("%d %d %d\n",x1 + 1,y1,3);
if((i - 1) % 4 == 0) printf("%d %d %d\n",x1 - 1,y1,1);
if((i - 2) % 4 == 0) printf("%d %d %d\n",x1 + 1,y1,3);
}
}
return 0;
}
7-6 不管是谁都最喜欢 (15分)
map的应用。注意是结尾等于!所以要用substr截断;再者坑点是重复输出,用map去重~
#include
#include
#include
#include
#include
using namespace std;
map<string, bool> mp;
vector<string> VTUBER;
vector<string> DD;
int a;
string s, buff, s1 = "_official", s2 = "_0fficial", s3 = "_officiaI", s4 = "_0fficiaI";
int main(){
scanf("%d",&a);
while(cin >> s){
int len = s.length();
if(len >= 9){
buff = s.substr(len - 9);
if(!mp.count(s) && buff == s1){
VTUBER.push_back(s);
mp[s] = true;
}else if(!mp.count(s) && (buff == s2 || buff == s3 || buff == s4)){
DD.push_back(s);
mp[s] = true;
}
}
}
printf("%d %d\n",VTUBER.size(), DD.size());
for(int i = 0; i < VTUBER.size(); ++i)
cout << VTUBER[i] << endl;
for(int i = 0; i < DD.size(); ++i)
cout << DD[i] << endl;
return 0;
}
7-7 代码统计 (20分)
这不是PAT的题嘛QWQ 柱状图输出字母统计~注意输出格式 行末空格的问题!
#include
#include
#include
int book[30],maxx;
char c;
int main(){
while((c = getchar()) != EOF){
if(isalpha(c)){
book[toupper(c) - 'A' + 1]++;
if(maxx < book[toupper(c) - 'A' + 1]) maxx = book[toupper(c) - 'A' + 1];
}
}
for(int i = maxx; i >= 1; --i){
for(int j = 1; j <= 26; ++j){
if(j != 26){
if(book[j] >= i){
printf("* ");
book[j]--;
}else printf(" ");
}else{
if(book[j] >= i){
printf("*");
book[j]--;
}else printf(" ");
}
}
putchar('\n');
}
for(int i = 0; i < 26; ++i)
(i == 25) ? printf("%c",'A' + i) : printf("%c ",'A' + i);
return 0;
}
7-11 动物王国 (25分)
模拟就好啦……根据题意写~
#include
#include
using namespace std;
int n,q,x,y;
int fa[100005],cake[100005];
void solve(int x, int y){
int start = x, end = y;
while(start != end){
cake[start]++;
start = fa[start];
}
}
int main(){
scanf("%d%d",&n,&q);
for(int i = 1; i <= n; ++i){
scanf("%d",&fa[i]); //被管理
}
for(int i = 1; i <= q; ++i){
scanf("%d%d",&x,&y);
solve(x,y);
}
for(int i = 1; i <= n; ++i)
(i == 1) ? printf("%d",cake[i]) : printf(" %d",cake[i]);
return 0;
}
7-12 传话的难度 (25分)
标准的mst(最小生成树)算法。个人习惯使用kruskal。注意一点就是求的是最大的传话难度,不是总的难度~
#include
#include
using namespace std;
const int maxn = 200005;
int n,m,f[maxn],ans,cnt;
struct node{
int u,v,w;
}book[maxn];
int cmp(node n1, node n2){return n1.w < n2.w;}
int find(int x){return f[x] == x ? x : f[x] = find(f[x]);}
int unite(int x, int y){
int fa = find(x), fb = find(y);
if(fa == fb) return 0;
else f[fb] = f[fa];
return 1;
}
void init(){
for(int i = 1; i <= n; ++i) f[i] = i;
cnt = 0;
}
int main(){
scanf("%d%d",&n,&m);
init();
for(int i = 1; i <= m; ++i)
scanf("%d%d%d",&book[i].u,&book[i].v,&book[i].w);
sort(book + 1, book + 1 + m, cmp);
//kruskal
int i;
for(i = 1; i <= m; ++i){
if(unite(book[i].u, book[i].v))
cnt++; //只要看最大的,这里不用统计~
if(cnt == n - 1){
ans = book[i].w;
break;
}
}
printf("%d",ans);
return 0;
}
顺便复习一下并查集的模板/Kruskal的模板~
并查集(简单的版本):
void init(){
for(int i = 1; i <= n; ++i)
f[i] = i;
}
int find(x){return f[x] == x ? x : f[x] = find(f[x]);}
void unite(int x,int y){f[find(y)] = f[find(x)];}
bool check(int x, int y){return find(x) == find(y);}
Kruskal核心代码:
int unite(int x,int y){ //并(和一般并查集不太一样)
int r1 = find(x),r2 = find(y);
if(r1 == r2) return 0;
else{
f[r2] = f[r1];
return 1;
}
}
for(int i = 0; i < m; ++i){ //m是边数
if(unite(city[i].u, city[i].v)){
ans += city[i].w; //计算总边权
cnt++;
}else continue;
if(cnt == n - 1)
break;
}
未完待续~