开始准备cccc(cry)天梯赛了,第一周训练题,把官网挂出的训练题刷完了,对pat有了一点点的熟悉感。
L1-1 就不说了。。。
L1-2 打印沙漏
一个变量保存空格数,一个变量保存沙漏符号数,打印就行了,但这题话说wrong好几次啊,坑点是沙漏符号后面不打印空格,orz。。。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int main(){
int n;
char c;
scanf("%d %c",&n,&c);
int a[1010];
a[0] = 0;
a[1] = 1;
for(int i=2;i<1010;i++){
a[i] = a[i-1] + (2*i - 1)*2;
}
int t = 0;
for(;t<1010;t++){ //找到最大一层
if(n=1;i--){ //打印上一半
for(int j=0;j
//中间只有一个
for(int i=2;i<=t;i++){ //打印下一半
for(int j=0;j
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int main(){
int a[11];
memset(a,0,sizeof(a));
char n[1010];
scanf("%s",n);
int len = strlen(n);
if(len==1&&n[0]=='0') a[0]++;
while(len){
a[n[--len]-'0']++;
}
for(int i=0;i<10;i++){
if(a[i]){
printf("%d:%d\n",i,a[i]);
}
}
return 0;
}
L1-4 计算摄氏温度
怎么感觉在凑字数。。。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int main(){
int n;
scanf("%d",&n);
printf("Celsius = %d\n",5*(n-32)/9);
return 0;
}
hash,用了map,对应一下就行
#include
#include
#include
#include
#include
#include
#include
#include
L1-6 连续因子
暴力的解法,从改数的平方根开始先前查找,当该次查找结束且长度比之前长则更新,因为从后往前扫,保证更新的数为最小
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int main(){
int N;
scanf("%d",&N);
int n = 0;
char a[1010];
char temp[1010];
int tn = 0;
int status = 1;
for(int i = (int)sqrt(N)+1;i>=2&&status;i--){
tn = 0;
if(N%i==0){
temp[tn++] = i;
int t = N/i;
for(int j = i-1;j>=2;j--){
if(t%j==0){
temp[tn++] = j;
t/=j;
if(j==2){
status = 0;
}
}
else{
temp[tn] = 0;
break;
}
}
if(tn>=n){
strcpy(a,temp);
n = tn;
}
}
}
if(n==0){
printf("%d\n%d\n",n+1,N);
}
else{
printf("%d\n",n);
for(int j=n-1;j>=0;j--){
printf("%d",a[j]);
if(j!=0){
printf("*");
}
else{
printf("\n");
}
}
}
return 0;
}
字符串存储,对应即可
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
char a[10][10] = {"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
int main(){
string s;
cin>>s;
int len = s.size();
int i=0;
if(s[i]=='-'){
printf("fu ");
i++;
}
for(;i
打印数字一个变量记行,一个变量计数
求和 要考虑正数和负数
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int main(){
int a,b;
scanf("%d%d",&a,&b);
int n = b-a+1;
for(int i=0;i=0||b<=0){
printf("Sum = %d\n",(b-a+1)*(b+a)/2);
}
else{
printf("Sum = %d\n",(b-0+1)*(b+0)/2 + (0-a+1)*(0+a)/2);
}
return 0;
}
求最短路径,使用广度优先搜索,要求输出最短路径的条数和路径。
最短路并且要求救援队的数量最多,那么使用优先队列,按照步数来进行排序,相同步数则救援队数量最多,则当广度优先搜索搜索到目的地时,求得的步数为结果,当步数大于已求得的结果,则搜索结束。
路径使用数组保存,每搜索一个点,与当前已标记的点去比较,步数最小且救援队数量最多则更新路径数组,路径输出则从D查找到S即可。
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int c[510]; //每个城市的救援队数量
int a[510][510]; //存储步数
int book[510]; //记录路径
int cunt;
int step;
int ttime;
struct node{
int c; //救援队
int s; //步数
int n; //当前节点
int o; //前一个节点
bool operator <(const node& x) const{ //优先级:先排列步数,再排列救援队数目
if(s==x.s){
return cx.s;
}
}
};
int N,M,S,D;
void serach(int t);
void fin();
int main(){
scanf("%d%d%d%d",&N,&M,&S,&D);
for(int i=0;i q; //优先队列
q.push(p);
while(!q.empty()){
node t = q.top();
q.pop();
if(book[t.n]<0){ //记录路径
book[t.n] = t.o;
}
if(t.s>step) { //已求得结果,退出
return ;
}
else if(t.n==D&&t.s==step){ //最短路径计数
ttime++;
}
else if(t.n==D){ //最优路径
step = t.s;
ttime++;
cunt = t.c;
}
node temp;
temp.o = t.n;
for(int i=0;i=0){ //未广搜且联通
temp.n = i;
temp.c = t.c+c[i];
temp.s = t.s + a[t.n][i];
q.push(temp);
}
}
}
}
本体借鉴feng同学思路,感谢^_^
把所有点保存,设一个标记数组,从头结点开始,若当前点值未存在,存进一个数组,否则存进另一个,最后顺序输出即可。注意输出,从第二个节点开始要输出两遍自身地址,因为前后有可能地址并不对应。
输出技巧:%05d 即可输出5位,前面补0
#include
#include
#include
#include
#include
#include
#include
排下序,计算就可以了,注意精度
#include
#include
#include
#include
#include
#include
#include
using namespace std;
struct node{
double num;
double mon;
bool operator <(const node& x)const{
return mon*x.num>num*x.mon?1:0; //没有用除法,把分数化成同分母比较,会减少误差
}
};
int main(){
int n;
double m;
node a[1010];
scanf("%d%lf",&n,&m);
for(int i=0;i=a[i].num){ //最后的错误点 ’= ’ 精度要求很高!
sum += a[i].mon;
m-=a[i].num;
}
else if(m>0&&m
建树了,建一颗正常搜索树,再建一颗镜像搜索树,分别比较是否符合即可
#include
#include
#include
#include
using namespace std;
struct node{
int k;
struct node* left;
struct node* right;
};
int N;
int a[1010];
int tt[1010];
struct node* tree1;
struct node* tree2;
void pos(struct node* t);
void pre(struct node* t,int& x);
struct node* init1(struct node* t,int v);//正常
struct node* init2(struct node* t,int v);//镜像
int main(){
scanf("%d",&N);
tree1 = tree2 = NULL;
for(int i=0;i //前序
int status = 0;
for(int i=0;ileft);
pos(t->right);
if(t==tree1||t==tree2){
printf("%d\n",t->k);
}
else{
printf("%d ",t->k);
}
}
//前序
void pre(struct node* t,int& x){
if(t!=NULL&&xk;
x++;
pre(t->left,x);
pre(t->right,x);
}
}
struct node* init1(struct node* t,int v){
if(t==NULL){
t = (struct node*)malloc(sizeof(struct node));
t->k = v;
t->left = t->right = NULL;
return t;
}
if(vk){
t->left = init1(t->left,v);
}
else{
t->right = init1(t->right,v);
}
return t;
}
struct node* init2(struct node* t,int v){
if(t==NULL){
t = (struct node*)malloc(sizeof(struct node));
t->k = v;
t->left = t->right = NULL;
return t;
}
if(v>=t->k){
t->left = init2(t->left,v);
}
else{
t->right = init2(t->right,v);
}
return t;
}
普通01背包,装满背包,dp[]中保存用的零钱个数,零钱用的越多,肯定数最小,我排了下序,好像不排序也可以
dfs强剪枝也可以
#include
#include
#include
#include
using namespace std;
int book[110]; //路径
int v[110]; //用于路径中比较值
void input(int x);//输出,我起错名了。。。
int main(){
int N,M;
int a[10010];
scanf("%d%d",&N,&M);
for(int i=0;i //注意装满应该为无穷小
book[i] = -1;
}
dp[0] = 0;
for(int i=0;i=a[i];j--){
if(dp[j]<=dp[j-a[i]]+1){
dp[j] = dp[j-a[i]]+1;
book[j] = j-a[i];
v[j] = a[i];
}
}
}
if(dp[M]>0){
input(M);
printf("\n");
}
else{
printf("No Solution\n");
}
return 0;
}
void input(int x){
if(book[x]==0){
printf("%d",v[x]);
return ;
}
input(book[x]);
printf(" %d",v[x]);
}
单点更新查询,用线段树,保存本区间内的点数
#include
#include
#include
#include
#include
#define lson l,m,level*2
#define rson m+1,r,level*2+1
using namespace std;
int a[100010];
int tree[100010*5];
void init(int l,int r,int level);
void find(int l,int r,int level,int x);
void update(int l,int r,int level,int x,int s);
int main(){
int N;
scanf("%d",&N);
stacks;
getchar();
int mmax = 100002;
memset(a,0,sizeof(a));
memset(tree,0,sizeof(tree));
//init(1,100000,1);
while(N--){
char c[30];
int num;
scanf("%s",c);
if(!strcmp(c,"Pop")){
if(!s.empty()){
printf("%d\n",s.top());
update(1,mmax,1,s.top(),0);
a[s.top()]--;
s.pop();
}
else{
printf("Invalid\n");
}
}
else if(!strcmp(c,"PeekMedian")){
int n = s.size();
if(n>0){
if(n%2==1){ //注意奇偶数
n++;
}
find(1,mmax,1,n/2);
}
else{
printf("Invalid\n");
}
}
else if(!strcmp(c,"Push")){
scanf("%d",&num);
s.push(num);
a[num]++;
if(mmax>1;
if(x<=m){
update(lson,x,b);
}
else{
update(rson,x,b);
}
tree[level] = tree[level*2+1] + tree[level*2];
}
void find(int l,int r,int level,int x){
if(l==r&&(x<=tree[level])){
printf("%d\n",l);
return ;
}
int m = (l+r)>>1;
if(tree[level*2]>=x){
find(lson,x);
}
else{
find(rson,(x-tree[level*2]));
}
}
void init(int l,int r,int level){
if(l==r){
tree[level] = a[l];
return ;
}
int m = (l+r)>>1;
init(lson);
init(rson);
tree[level] = tree[level*2] + tree[level*2+1];
}
vector数组为活动号,保存选择该活动的人员编号。从第一个人i开始查找,所有和本人在同一活动中的人全部入队,并标记上i,并对队的每个人进行相同查找,直到队空。i++,在进行下一个没有查找过的人的查找到结束。
最后计算标记数组中共出现的标号和数量,排序输出。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
vector a[1010];
int main(){
int N;
scanf("%d",&N);
int mmax = 0;
for(int i=1;i<=N;i++){
int n;
scanf("%d:",&n);
for(int j=0;jq;
q.push(i);
while(!q.empty()){
int p = q.front();
q.pop();
for(int j=0;j<=mmax;j++){
if(a[j].size()!=0&&!y[j]&&find(a[j].begin(),a[j].end(),p)!=a[j].end()){
y[j] = 1;
for(int k=0;k());
int time = 0;
for(int i=0;c[i];i++){
time++;
}
printf("%d\n",time);
if(time){
printf("%d",c[0]);
for(int i=1;c[i];i++){
printf(" %d",c[i]);
}
printf("\n");
}
return 0;
}