A(桶排序):
/*年龄统计
朝宇妹这几天忙于统计科协所有会员的年龄,给你所有大于一周岁的人的年龄(单位:年),且已知没有人的年龄大于100岁,
请你将这些年龄升序排列
输入:
第一行是n——人数(0<n<=2000000)
第二行是n个人的年龄
输出:
输出n个分开的数字(年龄),升序排列。
样例输入:
5
2 3 2 3 1
样例输出:
1 2 2 3 3
例程:*/
#include <stdio.h>
#include <string.h>
const int N = 105;
int m[N], n;
int main() {
//freopen("F:\\现场编程大赛\\初赛\\普及组\\C\\in\\test0.in", "r", stdin);
//freopen("F:\\现场编程大赛\\初赛\\普及组\\C\\out\\test0.out", "w", stdout);
while (scanf("%d", &n)) {
memset(m, 0, sizeof(m));
int a, flag = 0;
for (int i = 0; i < n; i++) {
scanf("%d", &a);
m[a]++;
}
for (int i = 1; i <= 100; i++)
while (m[i]) {
if (flag)
printf(" %d", i);
else {
flag = 1;
printf("%d", i);
}
m[i]--;
}
printf("\n");
}
return 0;
}
B(模拟):
/*文件名
一橙小萌新这几天在整理文件,他觉得如果文件名有三个或以上的"x" (小写),这个文件的命名就不受欢迎,可以通过删除文件名中的x,使得文件名中不再 "xxx"这个字串,请求出最小的删除数目,有强迫症的他决定向机智的你求助。
例如:文件名为"exxxii",如果你删除第二个位置的字符,那么文件名变成"exxii",就会受欢迎了
输入:
第一行是n(3≤n≤100)——文件名的长度
第二行是文件名
输出:
输出最小的删除数目,如果本来文件名就很受欢迎,输出0
样例输入:
6
xxxiii
样例输出:
1
例程:*/
#include "iostream"
using namespace std;
const int Max=1e2+10;
char ch[Max];
int main()
{
int n,ans=0;
cin>>n>>ch;
for(int i=0;i<n-2;i++){
if(ch[i]=='x'&&ch[i+1]=='x'&&ch[i+2]=='x')
ans++;
}
cout<<ans<<endl;
return 0;
}
C(模拟):
/*18岁生日
王潇洒大朋友n的18岁生日就要到了,他当然很开心,可是他突然想到一个问题,
是不是每个人从出生开始,到达18岁生日时所经过的天数都是一样的呢?
似乎并不全都是这样,所以他想请你帮忙计算一下他和他的几个朋友从出生到达18岁生日所经过的总天数,让他好来比较一下。
输入:
一个数T,后面T行每行有一个日期,格式是YYYY-MM-DD。如我的生日是1988-03-07。
输出:
T行,每行一个数,表示此人从出生到18岁生日所经过的天数。如果这个人没有18岁生日,就输出-1。
样例输入:
1
1988-03-07
样例输出:
6574
例程:*/
#include<iostream>//注意找规律,不要一天一天的模拟
#include<string>
using namespace std;
bool is_leap(int year){
if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)){
return true;
}else{
return false;
}
}
int main(){
//freopen("F:\\现场编程大赛\\初赛\\普及组\\D\\in\\test0.in", "r", stdin);
//freopen("F:\\现场编程大赛\\初赛\\普及组\\D\\out\\test0.out", "w", stdout);
int m;
cin>>m;
string s;
int year;
int month;
int day;
int count;
for(int i = 0; i < m; i++){
cin>>s;
year = (s[0] - 48) * 1000 + (s[1] - 48) * 100 + (s[2] - 48) * 10 + (s[3] - 48);
month = (s[5] - 48) * 10 + (s[6] - 48);
day = (s[8] - 48) * 10 + (s[9] - 48);
if(is_leap(year) && month == 2 && day == 29){
cout<<-1<<endl;
continue;
}
count = 0;
if(month <= 2){
if(is_leap(year)){
count++;
}
}
year++;
for(int j = 1; j <= 18; year++, j++){
if(is_leap(year)){
count++;
}
}
year--;
if(is_leap(year) && month <= 2){
count--;
}
cout<<6570 + count<<endl;
}
}
D(等差数列):
/*总和问题
赵甜甜同学酷爱数学,有一天他看到书上有这样一个题目,给定序列1,2,3,...... N,你的任务是计算子序列之和为M的所有可能的子序列。他好像被难住了,只好向你求助。
输入:
第一行为N和M( 1 <= N, M <= 1000000000)
输出:
输出所有可能的子序列,格式见样例
样例输入:
50 30
样例输出:
[4,8]
[6,9]
[9,11]
[30,30]
例程:
/*这题主要要找到切入口(等差公式):假如有满足题意的情况:a+1,a+2,a+3,........a+n=m;即:(n*a)+n*(n+1)/2=m可以得到;n*n<2*m。
通过for循环,从1,2,3,........n,全部遍历一遍,查找满足条件的情况,即使得(n*a)+n*(n+1)/2=m成立(n,m已知,只需求出a,若a存在,则说明该种情况符合)
输出:[a+1,a+n].
*/*/
#include <iostream>
#include <cmath>
#include <iomanip>
#include <string>
using namespace std;
int main(void)
{
//freopen("F:\\现场编程大赛\\初赛\\普及组\\E\\in\\test10.in", "r", stdin);
//freopen("F:\\现场编程大赛\\初赛\\普及组\\E\\out\\test0.out", "w", stdout);
int n,m;
cin>>n>>m;
for(int i=sqrt(2*m);i>=1;i--)
{
int a=(m-((i-1)*i)/2)/i;
if(m==a*i+(i*(i-1))/2&&a>0)
if(a>=1&&a+i-1<=n)
cout<<'['<<a<<','<<a+i-1<<']'<<endl;
}
cout<<endl;
return 0;
}
E(并查集模板) :
/*多少桌子
今天是粥粥的生日。她邀请了很多朋友。现在是晚餐时间。粥粥想知道她至少需要多少桌子。
你必须知道并非所有的朋友都互相认识,而且所有的朋友都不想和陌生人呆在一起。这个问题的一个重要规则是,
如果我告诉你A知道B,B知道C,那意味着A,B,C彼此了解,所以他们可以留在一个桌子。
例如:如果我告诉你A知道B,B知道C,D知道E,所以A,B,C可以留在一个桌子,
D,E必须留在另一个桌子。所以粥粥至少需要2张桌子。
输入:
以两个整数N和M开始(1 <= N,M <= 1000)。N表示朋友的数量,朋友从1到N标记。然后M行数据。
每一行由两个整数A和B(A!= B)组成,这意味着朋友A和朋友B彼此了解
输出:
对于每个测试用例,只输出粥粥至少需要多少个表。
样例输入:
5 3
1 2
2 3
4 5
样例输出:
2
例程:*/
#include<cstdio>
#include<iostream>
using namespace std;
int fa[1005];
int n,m;
void init()
{
for(int i=0;i<1005;i++)
fa[i]=i;
}
int findd(int x)
{
if(fa[x]!=x)
fa[x]=findd(fa[x]);
return fa[x];
}
void unionn(int x,int y)
{
int a=findd(x),b=findd(y);
if(a!=b)
fa[b]=a;
else return;
}
int main()
{
//freopen("F:\\现场编程大赛\\初赛\\普及组\\F\\in\\test0.in", "r", stdin);
//freopen("F:\\现场编程大赛\\初赛\\普及组\\F\\out\\test0.out", "w", stdout);
int n, m;
int a,b,cnt=0;
scanf("%d%d",&n,&m);
init();
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
unionn(a,b);
}
for(int i=1;i<=n;i++)
{
findd(i);
if(findd(i)==i)
cnt++;
}
printf("%d\n",cnt);
return 0;
}
F(字符串处理):
/*通配符匹配
qq学姐英语课闲来无事,看到了一个通配符的神奇定义。定义如下:你有两个字符串s和t,字符串s里面含有小写字母和最多一个'*',字符串t只含有小写字母。
s的长度是n,t的长度是m。
通配符'*'如果在s中可以用任意小写字母组成的字符串(可以是空串)替换之后,得到了t,
那么说明t和s是匹配的。
举个例子,若s= "aba*aba",那么以下字符串和它匹配:"abaaba", "abacaba" 和 "abazzzaba"
以下字符串就不匹配: "ababa", "abcaaba", "codeforces", "aba1aba", "aba?aba"
那么如果匹配就输出"YES",否则输出 "NO"
输入:
第一行是两个整数n和m(1≤n,m≤2*10^5) ——分别是字符串s的长度和字符串t的长度
第二行是字符串s
第三行是字符串t
输出:
如果可以从t可以得到s,就输出"YES"(没有引号),否则输出 "NO"(没有引号)
样例输入:
6 10
deco*s
decocesfor
样例输出:
NO
例程:*/
#include<stdio.h>
#include<string.h>
int main()
{
//freopen("F:\\现场编程大赛\\初赛\\普及组\\A\\in\\test0.in", "r", stdin);
int n, m;
while (~scanf("%d %d", &n, &m))
{
char s1[300005], s2[300005];
scanf("%s", s1);
getchar();
scanf("%s", s2);
if (n == m)//这里其实是最坑的,因为我只考虑了相等没有*,但是有的话如果其他的一样也是可以替换的,所以一开始直接判断一直被坑
{
for (int i = 0; i < n; i++)
{
if (s1[i] == '*')
{
s1[i] = s2[i];
break;
}
}
if (strcmp(s1, s2) == 0)
printf("YES\n");
else
printf("NO\n");
}
else if (n > m + 1)
{
printf("NO\n");
}
else if (n == m + 1)
{
for (int i = 0; i < n; i++)
{
if (s1[i] == '*')
{
for (int j = i; j < n - 1; j++)
{
s1[j] = s1[j + 1];
}
s1[n - 1] = '\0';
break;
}
}
if (strcmp(s1, s2) == 0)
printf("YES\n");
else
printf("NO\n");
}
else
{
int flag = 1;
int i;
for (i = 0; i < n; i++)
{
if (s1[i] == '*')
break;
}
if (i == n)
flag = 0;
else
{
for (int k = 0; k < i; k++)
{
if (s2[k] != s1[k])
{
flag = 0;
break;
}
}
for (int k = i + 1; k <n; k++)
{
if (s2[m - (n - k)] != s1[k])
{
flag = 0;
break;
}
}
}
if (flag)
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}