#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
int main()
{
int n,m;
while(scanf("%d%d",&n,&m))
{
if(n==0&&m==0)break;
int i,j;
int sum=0;
for(i=1;i<=n;i++){
sum+=i;
// sum=sum+i;
// sum-=i;
}
if(sum==m)
{
printf("%d\n",sum);
}
else if(sum<m)
{
printf("%d\n",m);
}
else {
printf("%d\n",sum+m);
}
}
return 0;
}
zoj1456 凸包
http://blog.youkuaiyun.com/l04205613/article/details/6401402
PAT1038 Recover the Smallest Number
由一道面试题改的 把数组排成最小的数
不同之处是这个是直接按字符串处理的
Sample Input:
5 32 321 3214 0229 87Sample Output:
22932132143287
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#include<map>
#define N 10010
#define INF 0x7fffffff
using namespace std;
string s[N];
bool cmp(string a,string b)
{
return a+b<b+a;
}
int main()
{
int n,i;
while(~scanf("%d",&n))
{
char ch[10];
for(i=0;i<n;i++){
scanf("%s",ch);
s[i]=ch;
}
sort(s,s+n,cmp);
string res="";
for(i=0;i<n;i++)res+=s[i];
i=0;
while(res[i]=='0')i++;
if(i==res.length())puts("0");
else {
puts(res.substr(i,res.length()-i).c_str());
}
}
return 0;
}
【百度面试题】把数组排成最小的数
问题描述:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个。例如输入数组{32, 321},则输出这两个能排成的最小数字32132。请给出解决问题的算法,并证明该算法。
思路:先将整数数组转为字符串数组,然后字符串数组进行排序,最后依次输出字符串数组即可。这里注意的是字符串的比较函数需要重新定义,不是比较a和b,而是比较ab与 ba。如果ab < ba,则a < b;如果ab > ba,则a > b;如果ab = ba,则a = b。比较函数的定义是本解决方案的关键。这道题其实就是希望我们能找到一个排序规则,根据这个规则排出来的数组能排成一个最小的数字。
证明:为什么这样排个序就可以了呢?简单证明一下。根据算法,如果a < b,那么a排在b前面,否则b排在a前面。可利用反证法,假设排成的最小数字为xxxxxx,并且至少存在一对字符串满足这个关系:a > b,但是在组成的数字中a排在b前面。根据a和b出现的位置,分三种情况考虑:
(1)xxxxab,用ba代替ab可以得到xxxxba,这个数字是小于xxxxab,与假设矛盾。因此排成的最小数字中,不存在上述假设的关系。
(2)abxxxx,用ba代替ab可以得到baxxxx,这个数字是小于abxxxx,与假设矛盾。因此排成的最小数字中,不存在上述假设的关系。
(3)axxxxb,这一步证明麻烦了一点。可以将中间部分看成一个整体ayb,则有ay < ya,yb < by成立。将ay和by表示成10进制数字形式,则有下述关系式,这里a,y,b的位数分别为n,m,k。
关系1: ay < ya => a * 10^m + y < y * 10^n + a => a * 10^m - a < y * 10^n - y => a( 10^m - 1)/( 10^n - 1) < y
关系2: yb < by => y * 10^k + b < b * 10^m + y => y * 10^k - y < b * 10^m - b => y < b( 10^m -1)/( 10^k -1)
关系3: a( 10^m - 1)/( 10^n - 1) < y < b( 10^m -1)/( 10^k -1) => a/( 10^n - 1)< b/( 10^k -1) => a*10^k - a < b * 10^n - b =>a*10^k + b < b * 10^n + a => a < b
这与假设a > b矛盾。因此排成的最小数字中,不存在上述假设的关系。
综上所述,得出假设不成立,从而得出结论:对于排成的最小数字,不存在满足下述关系的一对字符串:a > b,但是在组成的数字中a出现在b的前面。从而得出算法是正确的。
1039. Course List for Student (25)
这题的学生数N不止40000 ,坑, 直接用map 去查找string对应的容器标超时,非要用hash,也真是够了,66666
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#include<map>
#include<vector>
#define INF 0x7fffffff
using namespace std;
const int MAX_STU = 26*26*26*10+10;
vector<int>a[MAX_STU];
int hashName(const char * name){
return (name[0]-'A')*26*26*10+(name[1]-'A')*26*10+(name[2]-'A')*10+(name[3]-'0');
}
int main()
{
int n,m,num;
char na[5];
while(~scanf("%d%d",&n,&m))
{
num=0;
for(int i=0;i<=MAX_STU;i++)a[i].clear();
while(m--)
{
int cur,stu;
scanf("%d%d",&cur,&stu);
while(stu--){
scanf("%s",na);
a[hashName(na)].push_back(cur);
// if(num>40001)while(1);
}
}
for(int i=0;i<=MAX_STU;i++)sort(a[i].begin(),a[i].end());
while(n--)
{
scanf("%s",na);
printf("%s",na);
int p=hashName(na);
printf(" %d",a[p].size());
for(int i=0;i<a[p].size();i++)printf(" %d",a[p][i]);
puts("");
}
}
return 0;
}
pat1042 感觉可以改编成一道找规律的题
PAT1014
容易出错的地方:是在17:00及以后开始服务的客户输出"Sorry",而不是17:00之前结束服务的输出"Sorry";
过了下面两个例子就好了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#define INF 0x7fffffff
#define N 500000
using namespace std;
int n,m,k,Q;
struct ss
{
int id;
int cost;
int endtime;
}t;
queue<ss>q[30],que;
int timer[30];
int getqueue()
{
int mi=20;
for(int i=1;i<=n;i++)if(q[i].size()<mi)mi=q[i].size();
if(mi>=m)return -1;
for(int i=1;i<=n;i++)if(q[i].size()==mi)return i;
}
int main()
{
while(~scanf("%d%d%d%d",&n,&m,&k,&Q))
{
for(int i=1;i<=n;i++)while(!q[i].empty())q[i].pop();
while(!que.empty())que.pop();
for(int i=1;i<=n;i++)timer[i]=8*60;
for(int i=1;i<=k;i++)
{
t.id=i;
scanf("%d",&t.cost);
int p=getqueue();
if(p==-1)que.push(t);
else {
timer[p]+=t.cost;
t.endtime=timer[p];
q[p].push(t);
}
}
int ans[1010];
memset(ans,-1,sizeof(ans));
for(int T=8*60;T<=17*60;T++)
{
for(int i=1;i<=n;i++)
{
t=q[i].front();
if(t.endtime==T){
ans[t.id]=t.endtime;
// printf(" -- %d %d %d\n",t.id,t.cost,t.endtime-480);
q[i].pop();
/*
不存在t.cost=0
while(!q[i].empty()&&q[i].front().endtime==T){
ans[q[i].front().id]=t.endtime;
q[i].pop();
}
*/
}
}
int p;
while(!que.empty()&&(p=getqueue())!=-1)
{
t=que.front();
que.pop();
timer[p]+=t.cost;
t.endtime=timer[p];
// printf(" **%d %d %d %d\n",p,t.id,t.cost,t.endtime-480);
q[p].push(t);
}
}
for(int i=1;i<=n;i++)if(!q[i].empty()){
t=q[i].front();
if(t.endtime-t.cost<17*60)ans[t.id]=t.endtime;
}
int x;
while(Q--)
{
scanf("%d",&x);
if(ans[x]==-1)puts("Sorry");
else printf("%02d:%02d\n",ans[x]/60,ans[x]%60);
}
}
return 0;
}
/*
2 2 7 7
550 250 250 4 3 533 200
1 2 3 4 5 6 7
2 2 7 5
1 2 6 4 3 533 2
3 4 5 6 7
*/
ZOJ 1344
吃t
不清楚人一直在原地时应该怎么做?
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
int n,m,x1,y1,x2,y2,x3,y3,d;
char act[55];
char mapp[55][55],dogsight[55][55],vis[55][55];
int dy[4]={0,-1,0,1};
int dx[4]={-1,0,1,0};
int ans;
struct ss
{
int x,y;
int t;
}dog[55];
queue<ss>q;
void getdogsight(int t)
{
t=t%d;
int x=dog[t].x;
int y=dog[t].y;
int direct=dog[t].t;
memset(dogsight,0,sizeof(dogsight));
// printf("getdogsight %d %d %d\n",x,y,direct);
if(direct==0){
for(int i=x;i>=1;i--){
if(mapp[i][y]=='*')break;
dogsight[i][y]=1;
}
}
else if(direct==1){
for(int i=y;i>=1;i--){
if(mapp[x][i]=='*')break;
dogsight[x][i]=1;
}
}
else if(direct==2){
for(int i=x;i<=n;i++){
if(mapp[i][y]=='*')break;
dogsight[i][y]=1;
}
}
else {
for(int i=y;i<=m;i++){
if(mapp[x][i]=='*')break;
dogsight[x][i]=1;
}
}
/*
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)printf("%d",dogsight[i][j]);
printf("\n");
}
*/
}
int judside(int x,int y)
{
if(x>=1&&x<=n&&y>=1&&y<=m)return 1;
return 0;
}
void bfs()
{
memset(vis,0,sizeof(vis));
while(!q.empty())q.pop();
int x,y,t;
q.push((ss){x1,y1,0});
while(!q.empty())
{
x=q.front().x;
y=q.front().y;
t=q.front().t;
// printf(" %d %d %d\n",x,y,t);
if(x==x2&&y==y2){
ans=t;
return ;
}
//if(t>500)return;
q.pop();
int xx,yy;
getdogsight(t);
for(int i=0;i<4;i++)
{
xx=x+dx[i];
yy=y+dy[i];
if(judside(xx,yy)&&!vis[xx][yy]&&mapp[xx][yy]!='*'&&!dogsight[xx][yy])
{
vis[xx][yy]=1;
q.push((ss){xx,yy,t+1});
}
}
if(!dogsight[x][y])q.push((ss){x,y,t+1});
}
}
// 方向上左下右 0 1 2 3
int getdir(int f,int ind)
{
if(ind==0)return (f+1)%4;
else return (f+3)%4;
}
void getdogpath()
{
dog[0].x=x3;
dog[0].y=y3;
dog[0].t=0;//for(int i=0;i<1;i++)printf("%d %d %d %d\n",i,dog[i].x,dog[i].y,dog[i].t);
for(int i=0;i<d;i++)
{
if(act[i]=='G'){
if(mapp[dog[i].x+dx[dog[i].t]][dog[i].y+dy[dog[i].t]]=='*'){
dog[i+1].x=dog[i].x;
dog[i+1].y=dog[i].y;
dog[i+1].t=dog[i].t;
}
dog[i+1].x=dog[i].x+dx[dog[i].t];
dog[i+1].y=dog[i].y+dy[dog[i].t];
dog[i+1].t=dog[i].t;
}
else if(act[i]=='R'){
dog[i+1].x=dog[i].x;
dog[i+1].y=dog[i].y;
dog[i+1].t=getdir(dog[i].t,0);
}
else {
dog[i+1].x=dog[i].x;
dog[i+1].y=dog[i].y;
dog[i].t=getdir(dog[i].t,1);
}
}
for(int i=0;i<d;i++)dog[i]=dog[i+1];//狗走完一个循环的最后一步,回到原位不花时间
// for(int i=1;i<=d;i++)printf("%d %d %d %d\n",i,dog[i].x,dog[i].y,dog[i].t);
}
int main()
{
int k=1;
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0)break;
scanf("%d%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&x3,&y3,&d);
scanf("%s",act);
for(int i=1;i<=n;i++){
scanf("%s",mapp[i]);
for(int j=m;j>=1;j--)mapp[i][j]=mapp[i][j-1];
}
getdogpath();
/*
for(int t=1;t<=10;t++)
{
printf(" t= %d \n",t);
getdogsight(t);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
printf("%d",dogsight[i][j]);
}
printf("\n");
}
}
*/
ans=-1;
bfs();
if(k>1)printf("\n");
printf("Case %d:\n",k++);
if(ans!=-1)printf("Minimal time is: %d\n",ans);
else printf("No way out\n");
}
return 0;
}
AC代码:
#include<iostream>
#include<string>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
string maze[51];
char action[51];
int m,n,k,t,D,X1,X2,X3,Y1,Y2,Y3,flag,mark[51][51][51];
typedef struct
{
int x,y;
int step;
}Mov;
int patrol[51][3];//fatdog巡逻路线表:[0],[1]表示位置,[2]表示方向
int act[5][2]={{0,0},{-1,0},{1,0},{0,-1},{0,1}};
bool judge(Mov t)
{
int i;
if(patrol[k][0]==t.x)//狗和人在同一行
{
if(patrol[k][1]>t.y)//狗在人右边
{
if(patrol[k][2]==3)//狗朝左
{
for(i=t.y+1;i<patrol[k][1];i++)//检测人和狗之间有无墙
{
if(maze[t.x][i]=='*')
return 1;
}
return 0;
}
else
{
return 1;
}
}
else if(patrol[k][1]<t.y)
{
if(patrol[k][2]==4)
{
for(i=patrol[k][1]+1;i<t.y;i++)
{
if(maze[t.x][i]=='*')
return 1;
}
return 0;
}
else
{
return 1;
}
}
}
else if(patrol[k][1]==t.y)//狗和人在同一列
{
if(patrol[k][0]>t.x)//狗在人上面
{
if(patrol[k][2]==1)
{
for(i=t.x+1;i<patrol[k][0];i++)
{
if(maze[i][t.y]=='*')
return 1;
}
return 0;
}
else
{
return 1;
}
}
else if(patrol[k][0]<t.x)
{
if(patrol[k][2]==2)
{
for(i=patrol[k][0]+1;i<t.x;i++)
{
if(maze[i][t.y]=='*')
return 1;
}
return 0;
}
else
{
return 1;
}
}
}
return 1;
}
bool check(Mov t)
{
if(t.step%D==0)
k=D;
else
k=t.step%D;
if(mark[t.x][t.y][k]==0&&(!(patrol[k][0]==t.x&&patrol[k][1]==t.y))/*不走到狗身上*/)
return 1;
else
return 0;
}
void bfs()
{
if(X1==X2&&Y1==Y2)
{
flag=1;
cout<<"Minimal time is: "<<0<<endl;
return ;
}
queue<Mov> q;
Mov f,c,temp;
int i;
f.step=0;
f.x=X1;
f.y=Y1;
mark[f.x][f.y][f.step%(D+1)]=1;
q.push(f);
while(!q.empty())
{
c=q.front();
q.pop();
for(i=0;i<5;i++)
{
temp.step=c.step+1;
temp.x=c.x+act[i][0];
temp.y=c.y+act[i][1];
if(
(temp.x>=0&&temp.x<m&&temp.y>=0&&temp.y<n)/*在迷宫内部*/
&&(maze[temp.x][temp.y]!='*')/*墙不能走*/
&&(check(temp))
&&(judge(temp))/*不能在狗的视线之内)*/
)
{
if(temp.x==X2&&temp.y==Y2)
{
flag=1;
cout<<"Minimal time is: "<<temp.step<<endl;
return ;
}
mark[temp.x][temp.y][k]=1;
q.push(temp);
}
}
}
}
int main()
{
int i,ca;
ca=1;
while(scanf("%d %d",&m,&n))
{
if(m==0&&n==0)
break;
scanf("%d%d%d%d%d%d%d",&X1,&Y1,&X2,&Y2,&X3,&Y3,&D);
X1--;Y1--;X2--;Y2--;X3--;Y3--;//0,1对应
patrol[0][0]=X3;
patrol[0][1]=Y3;
patrol[0][2]=1;
for(i=1;i<=D;i++)
{
cin>>action[i];
if(action[i]=='G')
{
if(patrol[i-1][2]==1)//N
{
patrol[i][0]=patrol[i-1][0]-1;
patrol[i][1]=patrol[i-1][1];
patrol[i][2]=1;
}
else if(patrol[i-1][2]==2)//S
{
patrol[i][0]=patrol[i-1][0]+1;
patrol[i][1]=patrol[i-1][1];
patrol[i][2]=2;
}
else if(patrol[i-1][2]==3)//W
{
patrol[i][0]=patrol[i-1][0];
patrol[i][1]=patrol[i-1][1]-1;
patrol[i][2]=3;
}
else if(patrol[i-1][2]==4)//E
{
patrol[i][0]=patrol[i-1][0];
patrol[i][1]=patrol[i-1][1]+1;
patrol[i][2]=4;
}
}
else if(action[i]=='L')
{
patrol[i][0]=patrol[i-1][0];
patrol[i][1]=patrol[i-1][1];
if(patrol[i-1][2]==1)
{
patrol[i][2]=3;
}
else if(patrol[i-1][2]==2)
{
patrol[i][2]=4;
}
else if(patrol[i-1][2]==3)
{
patrol[i][2]=2;
}
else if(patrol[i-1][2]==4)
{
patrol[i][2]=1;
}
}
else if(action[i]=='R')
{
patrol[i][0]=patrol[i-1][0];
patrol[i][1]=patrol[i-1][1];
if(patrol[i-1][2]==1)
{
patrol[i][2]=4;
}
else if(patrol[i-1][2]==2)
{
patrol[i][2]=3;
}
else if(patrol[i-1][2]==3)
{
patrol[i][2]=1;
}
else if(patrol[i-1][2]==4)
{
patrol[i][2]=2;
}
}
}
for(i=0;i<m;i++)
{
cin>>maze[i];
}//end of input
memset(mark,0,sizeof(mark));
if(ca!=1)
cout<<endl;
cout<<"Case "<<ca++<<":"<<endl;
flag=0;
bfs();
if(flag==0)
cout<<"No way out"<<endl;
}
return 0;
}
pat1043
#include <iostream>
using namespace std;
int flag; //是否符合条件标志位,0符合,1不符合
struct node //树中的点
{
int value; //值
node *left,*right; //左右子树
};
node* Build1(int *data,int p,int q) //数据,起始、终止位置[p,q];
{
if(p>q)
return NULL;
if(flag==1) //不符合条件,直接跳出(应该放到最前)
return NULL;
node* root=new node;
root->value=data[p];
if(p==q) //只有一个数
{
root->left=NULL;
root->right=NULL;
return root;
}
int i;
int r=p; //第一个比data[p]大的数
for(i=p+1;i<=q;i++)
{
if(data[i]>=data[p])
{
r=i;
break;
}
}
if(r>p) //找得到比data[p]大的data[r]
{
for(i=r+1;i<=q;i++)
{
if(data[i]<data[p])
{
flag=1;
return NULL;
}
}
root->left=Build1(data,p+1,r-1);
root->right=Build1(data,r,q);
}
else //找不到
{
root->left=Build1(data,p+1,q);
root->right=NULL;
}
return root;
}
node* Build2(int *data,int p,int q) //镜像
{
if(p>q)
return NULL;
if(flag==1)
return NULL;
node* root=new node;
root->value=data[p];
if(p==q)
{
root->left=NULL;
root->right=NULL;
return root;
}
int i;
int r=p;
for(i=p+1;i<=q;i++)
{
if(data[i]<data[p]) //注意镜像的定义
{
r=i;
break;
}
}
if(r>p)
{
for(i=r+1;i<=q;i++)
{
if(data[i]>=data[p])
{
flag=1;
return NULL;
}
}
root->left=Build2(data,p+1,r-1);
root->right=Build2(data,r,q);
}
else
{
root->left=Build2(data,p+1,q);
root->right=NULL;
}
return root;
}
int put_flag=0; //是否输出过信息标志位,用于跳过第一个空格
void Put_data(node *root)
{
if(root->left!=NULL)
Put_data(root->left);
if(root->right!=NULL)
Put_data(root->right);
if(put_flag==1)
cout<<" ";
else
put_flag=1;
cout<<root->value;
}
int main()
{
int n,data[1001]; //数据
int i;
cin>>n;
for(i=0;i<n;i++)
cin>>data[i];
if(n==1) //只有一个值,符合条件
{
cout<<"YES\n";
cout<<data[0];
return 0;
}
flag=0; //考虑正向
node *root=Build1(data,0,n-1);
if(flag==0)
{
cout<<"YES\n";
Put_data(root);
return 0;
}
flag=0; //考虑镜像
root=Build2(data,0,n-1);
if(flag==0)
{
cout<<"YES\n";
Put_data(root);
}
else //都不符合
cout<<"NO";
return 0;
}
这个题目是考察二查搜索树,但其实实际上并不需要我们建立一个二叉树,我们只需要在重构的过程中,利用递归的思想直接进行一次遍历即可。
本代码中使用到了lambda表达式,所以代码量比较简洁,只有40行,c++里面还真有很多有趣的特性。
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;
int N;
int A[1005];
vector<int> res;//存放输出结果
int value;//临时变量,用于lambda函数内部
function<int (int)> func = [=](int i){return i>=value;}; //lambda函数指针
void tree(int* a, int* b){
if(a>=b)
return; //递归出口
value = *a;
int* center = find_if(a+1,b,func); //数组分成3部分,分别是:根元素 左子树 右子树
if(!all_of(center,b,func)) //测试右子树是否满足条件
return;
tree(a+1,center); //遍历左子树
tree(center,b); //遍历右子树
res.push_back(*a); //存储输出
}
int main(){
scanf("%d",&N);
for(int i=0;i<N;i++){
scanf("%d",A+i);
}
if(N>1 && A[0]<=A[1])
func = ([=](int i){return i<value;});//如果是mirror,改变lambda函数
tree(A,A+N);
if(res.size()!=N)
printf("NO\n");
else{//输出
printf("YES\n");
printf("%d",res[0]);
for(int i=1;i<res.size();i++)
printf(" %d",res[i]);
}
return 0;
}
ZOJ1944 已知前序和中序求后序
不建树版
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char pre[30],in[30];
int num;
void Postorder(int l,int r)
{
if(l>r)return ;
if(l==r){
num++;
printf("%c",in[l]);
return;
}
int re=l;
for(int i=l;i<=r;i++)
{
if(in[i]==pre[num]){
re=i;
break;
}
}
num++;
Postorder(l,re-1);
Postorder(re+1,r);
printf("%c",in[re]);
}
int main()
{
int n;
while(~scanf("%s%s",pre,in))
{
num=0;
Postorder(0,strlen(pre)-1);
printf("\n");
}
return 0;
}
建树版
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char pre[30],in[30];
struct node
{
char value;
node *left,*right;
};
int num;
node* Build(int l,int r)
{
// printf("%d %d %d\n",num,l,r);
node* root=new node;
root->value=pre[num];
if(l>r)return NULL;
if(l==r){
num++;
root->left=NULL;
root->right=NULL;
return root;
}
int i;
int re=l;
for(i=l;i<=r;i++)
{
if(in[i]==pre[num]){
re=i;
break;
}
}
num++;
root->left=Build(l,re-1);
root->right=Build(re+1,r);
return root;
}
void Put_data(node *root)
{
if(root->left!=NULL)Put_data(root->left);
if(root->right!=NULL)Put_data(root->right);
printf("%c",root->value);
}
int main()
{
int n;
while(~scanf("%s%s",pre,in))
{
num=0;
node* root=Build(0,strlen(in)-1);
Put_data(root);
printf("\n");
}
return 0;
}
pat1086 先序建树,后序输出,简单题
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct Node{
int value;
Node *leftChild;
Node *rightChild;
Node(int v):value(v),leftChild(NULL),rightChild(NULL){}
};
char ch[10];
int n,num;
int flag;
Node* Build(Node* root)
{
if(num>=2*n)return NULL;
scanf("%s",ch);
if(ch[1]=='u'){
root=new Node(0);
scanf("%d",&root->value);
num++;
root->leftChild=Build(root->leftChild);
root->rightChild=Build(root->rightChild);
}
else {
root=NULL;
num++;
}
return root;
}
void PutTree(Node *root)
{
if(root!=NULL){
PutTree(root->leftChild);
PutTree(root->rightChild);
if(!flag){
printf("%d",root->value);
flag=1;
}
else printf(" %d",root->value);
}
}
int main()
{
while(~scanf("%d",&n))
{
Node *root=NULL;
num=0;
flag=0;
root=Build(root);
PutTree(root);
puts("");
}
return 0;
}
POJ 3667 区间合并
http://www.cnblogs.com/kedebug/archive/2013/01/20/2868210.html
题意:
有N个房间,M次操作。1 a表示找到连续的长度为a的空房间,如果有多解,优先左边的,即表示入住。2 b len把起点为b长度的len的房
线段树的区间合并和查询:
1. sum[]表示区间内最大的连续房间数
2. lsum[], rsum[]分别表示区间从左边、右边起的连续房间数目
3. 主要是其中的更新过程比较繁琐,理清楚逻辑就不是那么难了
#include <cstdio>
#include <algorithm>
using namespace std;
#define lhs l, m, rt << 1
#define rhs m + 1, r, rt << 1 | 1
const int maxn = 50010;
int sum[maxn << 2], lab[maxn << 2];
int lsum[maxn << 2], rsum[maxn << 2];
enum __check { checkout = 0, checkin };
void PushDown(int rt, int m)
{
if (lab[rt] != -1)
{
lab[rt << 1] = lab[rt << 1 | 1] = lab[rt];
sum[rt << 1] = lsum[rt << 1] = rsum[rt << 1] = lab[rt] ? 0 : m - (m >> 1);
sum[rt << 1 | 1] = lsum[rt << 1 | 1] = rsum[rt << 1 | 1] = lab[rt] ? 0 : (m >> 1);
lab[rt] = -1;
}
}
void PushUp(int rt, int m)
{
lsum[rt] = lsum[rt << 1];
rsum[rt] = rsum[rt << 1 | 1];
if (lsum[rt] == m - (m >> 1))
lsum[rt] += lsum[rt << 1 | 1];
if (rsum[rt] == m >> 1)
rsum[rt] += rsum[rt << 1];
sum[rt] = max(rsum[rt << 1] + lsum[rt << 1 | 1], max(sum[rt << 1], sum[rt << 1 | 1]));
}
void Build(int l, int r, int rt)
{
sum[rt] = lsum[rt] = rsum[rt] = r - l + 1;
lab[rt] = -1;
if (l == r)
return ;
int m = (l + r) >> 1;
Build(lhs);
Build(rhs);
}
void Update(int beg, int end, __check c, int l, int r, int rt)
{
if (beg <= l && r <= end)
{
sum[rt] = lsum[rt] = rsum[rt] = c ? 0 : r - l + 1;
lab[rt] = c;
return ;
}
PushDown(rt, r - l + 1);
int m = (l + r) >> 1;
if (beg <= m)
Update(beg, end, c, lhs);
if (end > m)
Update(beg, end, c, rhs);
PushUp(rt, r - l + 1);
}
int Query(int w, int l, int r, int rt)
{
if (l == r)
return r;
PushDown(rt, r - l + 1);
int m = (l + r) >> 1;
if (sum[rt << 1] >= w)
return Query(w, lhs);
else if (rsum[rt << 1] + lsum[rt << 1 | 1] >= w)
return m - rsum[rt << 1] + 1;
else
return Query(w, rhs);
}
int main()
{
int n, m;
scanf("%d %d", &n, &m);
Build(1, n, 1);
for (int i = 0; i < m; ++i)
{
int op, a, b;
scanf("%d", &op);
if (op == 1)
{
scanf("%d", &a);
if (sum[1] >= a)
{
int p = Query(a, 1, n, 1);
printf("%d\n", p);
Update(p, p + a - 1, checkin, 1, n, 1);
}
else
printf("0\n");
}
else if (op == 2)
{
scanf("%d %d", &a, &b);
Update(a, a + b - 1, checkout, 1, n, 1);
}
}
return 0;
}
pat 1066 平衡二叉树的旋转插入
http://blog.youkuaiyun.com/tiantangrenjian/article/details/12891091
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct Node
{
int value;
int height;
Node *leftChild;
Node *rightChild;
Node(int v):value(v),leftChild(NULL),rightChild(NULL),height(0){}
};
int getHeight(Node *node)
{
if(node == NULL)return -1;
return node->height;
}
bool isBalance(Node* parent)
{
return abs(getHeight(parent->leftChild)-getHeight(parent->rightChild))<2;
}
Node* rotate_LL(Node* parent)
{
Node* child=parent->leftChild;
parent->leftChild=child->rightChild;
child->rightChild=parent;
parent->height = max(getHeight(parent->leftChild),getHeight(parent->rightChild))+1;
child->height = max(getHeight(child->leftChild),getHeight(child->rightChild))+1;
return child;
}
Node* rotate_RR(Node* parent)
{
Node* child=parent->rightChild;
parent->rightChild=child->leftChild;
child->leftChild=parent;
parent->height = max(getHeight(parent->leftChild),getHeight(parent->rightChild))+1;
child->height = max(getHeight(child->leftChild),getHeight(child->rightChild))+1;
return child;
}
Node* rotate_LR(Node* parent)
{
Node* child=parent->leftChild;
parent->leftChild=rotate_RR(child);
return rotate_LL(parent);
}
Node* rotate_RL(Node *parent)
{
Node* child=parent->rightChild;
parent->rightChild=rotate_LL(child);
return rotate_RR(parent);
}
Node* InsertNode(Node* root,int newValue)
{
if(root!=NULL)
{
if(newValue>root->value)
{
root->rightChild=InsertNode(root->rightChild,newValue);
if(!isBalance(root))
{
if(newValue>root->rightChild->value)
{
root=rotate_RR(root);
}
else root=rotate_RL(root);
}
}
else
{
root->leftChild=InsertNode(root->leftChild,newValue);
if(!isBalance(root))
{
if(newValue>root->leftChild->value)
root=rotate_LR(root);
else root=rotate_LL(root);
}
}
}
else{
root=new Node(newValue);
}
root->height=max(getHeight(root->leftChild),getHeight(root->rightChild))+1;
return root;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
int val;
Node *root=NULL;
for(int i=0;i<n;i++)
{
scanf("%d",&val);
root=InsertNode(root,val);
}
printf("%d\n",root->value);
}
return 0;
}
///
1044 16/25
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define N 100010
#define inf 0x7fffffff
int main()
{
int n,m,x;
int s[N];
while(~scanf("%d%d",&n,&m))
{
s[0]=0;
for(int i=1;i<=n;i++){
scanf("%d",&x);
s[i]=s[i-1]+x;
// printf("** %d %d\n",i,s[i]);
}
int flag=0;
int mi=inf,a,b;
for(int i=0;i<=n;i++)
{
int p=lower_bound(s+i,s+n+1,s[i]+m)-s;
// printf("--- %d %d\n",i,p);
if(s[p]==s[i]+m){
printf("%d-%d\n",i+1,p);
flag=1;
}
else if(s[p]-s[i]>m&&s[p]-s[i]<inf)
{
a=i+1;
b=p;
}
}
if(flag==0)
{
printf("%d-%d\n",a,b);
}
}
return 0;
}
/*
5 16
2 4 5 7 9
*/
pat1057 树状数组求中位数
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
#define lowbit(x) x&(-x)
#define N 100010
int c[N];
void add(int i,int val)
{
while(i<N)
{
c[i]+=val;
i+=lowbit(i);
}
}
int getsum(int i)
{
int sum=0;
while(i>0)
{
sum+=c[i];
i-=lowbit(i);
}
return sum;
}
int binsearch()
{
int l=1,r=100000;
int k=getsum(100000);
k=(k+1)/2;
while(l<r)
{
int mid=(l+r)>>1;
if(getsum(mid)>=k)r=mid;
else l=mid+1;
}
return r;
}
int main()
{
char op[20];
int n;
stack<int>q;
while(~scanf("%d",&n))
{
memset(c,0,sizeof(c));
while(!q.empty())q.pop();
while(n--)
{
scanf("%s",op);
if(strcmp(op,"Pop")==0)
{
if(q.empty())
{
printf("Invalid\n");
}
else {
printf("%d\n",q.top());
add(q.top(),-1);
q.pop();
}
}
else if(strcmp(op,"PeekMedian")==0)
{
if(q.empty()){
printf("Invalid\n");
}
else
{
printf("%d\n",binsearch());
}
}
else
{
int x;
scanf("%d",&x);
q.push(x);
add(x,1);
}
//for(int i=0;i<10;i++)printf(" ** %d %d\n",i,getsum(i));
}
}
return 0;
}
pat1059求一个数的所有素数因子
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
int main()
{
long long n,i;
while(~scanf("%lld",&n))
{
i=2;
int flag=1;
printf("%lld=",n);
if(n==1)printf("1");
while(1)
{
if(n%i==0)
{
n/=i;
if(flag){
printf("%lld",i);
flag=0;
}
else printf("*%lld",i);
int k=1;
while(n%i==0)
{
n/=i;
k++;
}
if(k>1)printf("^%d",k);
}
else i++;
if(i*i>n)
{
if(n!=1){
if(flag){
printf("%lld",n);
flag=0;
}
else printf("*%lld",n);
}
puts("");
break;
}
}
}
return 0;
}
pat 1082 1y 细节题 知道什么后面一定只能是什么判断一下即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<cmath>
using namespace std;
char num[20][10]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
char jin[10][10]={"Wan","Shi","Bai","Qian","Yi"};
int s[20];
int getwei(int n)
{
int sum=0;
int ss[20];
int k=0;
while(n)
{
ss[k++]=n%10;
n/=10;
sum++;
}
for(int i=0;i<k;i++)s[i]=ss[k-i-1];
return sum;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
int first=1;
if(n==0){
puts("ling");
continue;
}
if(n<0){
if(!first)printf(" ");
first=0;
printf("Fu");
n=-n;
}
int k=getwei(n);
if(k==1)
{
if(!first)printf(" ");
first=0;
puts(num[n]);
continue;
}
int pre=1,p0=0;
// 1: yi er san..
// 0: ling
// 2: Shi Bai Qian Wang
// 3: Yi
for(int i=0;i<k;i++)
{
// printf("i= %d pre= %d \n",i,pre);
if(s[i]!=0)
{
if(!first)printf(" ");
first=0;
printf("%s",num[s[i]]);
pre=1;
}
else
{
if(pre>=2&&i==p0){
if(!first)printf(" ");
first=0;
printf("%s",num[0]);
pre=0;
}
}
if(i==k-1)break;
int p=k-i-1;
if(pre!=0){
if(p%8==0){
if(!first)printf(" ");
first=0;
printf("%s",jin[4]);
pre=3;
}
else {
if(pre==1||(pre==2&&p%4==0)){
if(!first)printf(" ");
first=0;
printf("%s",jin[p%4]);
pre=2;
}
}
}
int j;
for(j=i+1;j<k;j++){
if(s[j]!=0){
p0=j-1;
break;
}
}
if(j>=k)break;
}
puts("");
}
return 0;
}
/*
-1000003
-10000003
*/
pat1078 哈希表二次探测
http://www.cnblogs.com/foreverking/articles/2339735.html
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<cmath>
using namespace std;
#define N 10010
int a[N],vis[N];
bool jud(int n)
{
if(n==1)return false;
for(int i=2;i<=sqrt(n);i++)
if(n%i==0)return false;
return true;
}
int main()
{
int m,n,i,j;
while(~scanf("%d%d",&m,&n))
{
memset(vis,0,sizeof(vis));
for(i=0;i<n;i++)
scanf("%d",&a[i]);
while(!jud(m))m++;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
int k=(a[i]+j*j)%m;
if(!vis[k])
{
vis[k]=1;
if(i==n-1)printf("%d\n",k);
else printf("%d ",k);
break;
}
}
if(j>=m){
if(i==n-1)printf("-\n");
else printf("- ");
}
}
}
return 0;
}
pat1049数学,找规律
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int main()
{
int n;
while(~scanf("%d",&n))
{
int f=1;
int ans=0;
int high,low,now;
while(n/f!=0)
{
//printf("f = %d\n",f);
high=n/(f*10);
low=n-(n/f)*f;
now=(n/f)%10;
if(now==0)ans+=high*f;
else if(now==1)ans+=high*f+low+1;
else ans+=high*f+f;
f*=10;
}
printf("%d\n",ans);
}
return 0;
}
pat1087
http://www.aichengxu.com/view/34533
做完后感觉我对Dijkstra算法的掌握程度有所提升了
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
using namespace std;
#define INF 2100000000
#define MAX 300
map<string,int>nameNum;
map<int,string>numName;
int n,m;
bool visited[MAX];
int cost[MAX][MAX];
int pre[MAX];
int dis[MAX];
int happyvalue[MAX];
int final_happyness[MAX];
int pre_city_cnt[MAX];
int road_cnt[MAX];
void inti()
{
char name1[5],name2[5];
scanf("%d%d%s",&n,&m,name1);
nameNum[name1]=0;
numName[0]=name1;
memset(visited,false,sizeof(visited));
memset(final_happyness,0,sizeof(final_happyness));
memset(pre_city_cnt,0,sizeof(pre_city_cnt));
memset(road_cnt,0,sizeof(road_cnt));
for(int i=0;i<n;i++)
{
dis[i]=INF;
for(int j=0;j<n;j++)cost[i][j]=INF;
}
for(int i=1;i<n;i++)
{
scanf("%s%d",name1,&happyvalue[i]);
nameNum[name1]=i;
numName[i]=name1;
}
int dist;
for(int i=0;i<m;i++)
{
scanf("%s%s%d",name1,name2,&dist);
cost[nameNum[name1]][nameNum[name2]]=cost[nameNum[name2]][nameNum[name1]]=dist;
}
}
void Dijkstra()
{
dis[0]=0;
road_cnt[0]=1;//入口值,一条入口路径
for(int k=0;k<n;k++)
{
int index=-1;
int mindis=INF;
for(int i=0;i<n;i++)
{
if(visited[i]==false&&dis[i]<mindis)
{
index=i;
mindis=dis[i];
}
}
// printf("** %d %d\n",index,mindis);
if(index==-1)
{
break;
}
visited[index]=true;
for(int i=0;i<n;i++)
{
if(dis[i]>dis[index]+cost[index][i])
{
road_cnt[i]=road_cnt[index];
dis[i]=dis[index]+cost[index][i];
final_happyness[i]=final_happyness[index]+happyvalue[i];
pre_city_cnt[i]=pre_city_cnt[index]+1;
pre[i]=index;
}
else if(dis[i]==dis[index]+cost[index][i])
{
road_cnt[i]+=road_cnt[index];
if(final_happyness[i]<final_happyness[index]+happyvalue[i])
{
final_happyness[i]=final_happyness[index]+happyvalue[i];
pre_city_cnt[i]=pre_city_cnt[index]+1;
pre[i]=index;
}
else if(final_happyness[i]==final_happyness[index]+happyvalue[i])
{
if(pre_city_cnt[i]>pre_city_cnt[index]+1)
{
pre_city_cnt[i]=pre_city_cnt[index]+1;
pre[i]=index;
}
}
}
}
}
}
void print(int city)
{
if(city==0)
{
int dest=nameNum[(string)"ROM"];
printf("%d %d %d %d\n",road_cnt[dest],dis[dest],final_happyness[dest],final_happyness[dest]/ pre_city_cnt[dest]);
printf("%s",numName[0].c_str());
}
else{
print(pre[city]);
printf("->%s",numName[city].c_str());
}
}
int main()
{
inti();
Dijkstra();
print(nameNum[(string)"ROM"]);
// puts("");
return 0;
}
pat1030 做法同1087 ,更懂了
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 550
#define INF 2100000000
int cost[maxn][maxn];
int price[maxn][maxn];
int dis[maxn];
int pri[maxn];
bool vis[maxn];
int pre[maxn];
int cityNum,roadNum,root,scourse;
void inti()
{
scanf("%d%d%d%d",&cityNum,&roadNum,&root,&scourse);
for(int i=0;i<cityNum;i++)
{
dis[i]=INF;
pri[i]=INF;
for(int j=0;j<cityNum;j++)
{
cost[i][j]=INF;
price[i][j]=INF;
}
}
int st,en,cos,ppri;
while(roadNum--)
{
scanf("%d%d%d%d",&st,&en,&cos,&ppri);
cost[st][en]=cost[en][st]=cos;
price[st][en]=price[en][st]=ppri;
}
memset(vis,false,sizeof(vis));
memset(pre,-1,sizeof(pre));
memset(pri,0,sizeof(pri));
}
void Dijkstra()
{
dis[root]=0;
for(int k=0;k<cityNum;k++)
{
int mindis=INF;
int index=-1;
for(int i=0;i<cityNum;i++)
{
if(!vis[i]&&dis[i]<mindis)
{
mindis=dis[i];
index=i;
}
}
if(index==-1)
{
break;
}
// printf("index=%d %d\n",index,mindis);
vis[index]=1;
for(int i=0;i<cityNum;i++)
{
if(dis[i]>dis[index]+cost[index][i])
{
dis[i]=dis[index]+cost[index][i];
pri[i]=pri[index]+price[index][i];
pre[i]=index;
// printf("i=%d index=%d %d\n",i,index,dis[i]);
}
else if(dis[i]==dis[index]+cost[index][i])
{
if(pri[i]>pri[index]+price[index][i])
{
pri[i]=pri[index]+price[index][i];
pre[i]=index;
}
}
}
}
}
void Output(int city)
{
if(city==root){
printf("%d",city);
return;
}
else{
Output(pre[city]);
printf(" %d",city);
}
}
int main()
{
inti();
Dijkstra();
Output(scourse);
printf(" %d %d\n",dis[scourse],pri[scourse]);
return 0;
}
pat1080 简单的结构体排序,就是喜欢上课这种编程风格,分inti(),work(),output() 模块,并且英语单词来表意,而不是a,b,c,d这样的符号
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;
#define maxn 40004
#define maxm 105
int stuNum,schNum,perNum;
int lastRank[maxn];
int schQuota[maxn];
vector<int>school[maxm];
struct student
{
int stuId;
int GE,GI;
int finGrade;
int perSchool[10];
int rankNum;
}stu[maxn];
bool cmp(student s1,student s2)
{
if(s1.finGrade==s2.finGrade)
{
return s1.GE>s2.GE;
}
return s1.finGrade>s2.finGrade;
}
bool isEqual(student s1,student s2)
{
if(s1.finGrade==s2.finGrade&&s1.GE==s2.GE)return true;
return false;
}
void inti()
{
scanf("%d%d%d",&stuNum,&schNum,&perNum);
for(int i=0;i<schNum;i++)scanf("%d",&schQuota[i]);
for(int i=0;i<stuNum;i++)
{
scanf("%d%d",&stu[i].GE,&stu[i].GI);
stu[i].finGrade=stu[i].GE+stu[i].GI;
for(int j=0;j<perNum;j++)scanf("%d",&stu[i].perSchool[j]);
stu[i].stuId=i;
}
sort(stu,stu+stuNum,cmp);
stu[0].rankNum=0;
for(int i=1;i<stuNum;i++)
{
if(isEqual(stu[i],stu[i-1]))stu[i].rankNum=stu[i-1].rankNum;
else stu[i].rankNum=i;
}
for(int i=0;i<schNum;i++)school[i].clear();
memset(lastRank,-1,sizeof(lastRank));
}
void select()
{
for(int i=0;i<stuNum;i++)
{
for(int j=0;j<perNum;j++)
{
// if(stu[i].stuId==5)printf("j=%d\n",stu[i].perSchool[j]);
int sId=stu[i].perSchool[j];
if(school[sId].size()<schQuota[sId])
{
school[sId].push_back(stu[i].stuId);
lastRank[sId]=stu[i].rankNum;
break;
}
else if(school[sId].size()>0&&stu[i].rankNum==lastRank[sId])
{
school[sId].push_back(stu[i].stuId);
break;
}
}
}
}
void output()
{
for(int i=0;i<schNum;i++)
{
if(school[i].size()==0)puts("");
else{
sort(school[i].begin(),school[i].end());
printf("%d",school[i][0]);
for(int j=1;j<school[i].size();j++)
{
printf(" %d",school[i][j]);
}
puts("");
}
}
}
int main()
{
inti();
select();
output();
return 0;
}
pat1076DFS+剪枝
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 1010
vector<int>user[maxn];
int userNum,maxLevel;
bool visited[maxn];
bool opened[maxn];
void inti()
{
scanf("%d%d",&userNum,&maxLevel);
for(int i=1;i<=userNum;i++)user[i].clear();
for(int i=1;i<=userNum;i++)
{
int num,to;
scanf("%d",&num);
while(num--)
{
scanf("%d",&to);
user[to].push_back(i);
}
}
/*
for(int i=1;i<=userNum;i++)
{
printf("i=%d \\",i);
for(int j=0;j<user[i].size();j++)
{
printf("%d ",user[i][j]);
}
puts("");
}
*/
}
void DFS(int root,int level)
{
// printf("%d %d %d\n",root,visited[root],level);
if(visited[root]&&opened[root])return;
//剪枝 opened表示root下的关注列表已经被展开过
visited[root]=true;
if(user[root].size()==0)
{
opened[root]=true;
return;
}
if(level<maxLevel){
opened[root]=true;
for(int i=0;i<user[root].size();i++)
{
DFS(user[root][i],level+1);
}
}
}
void work()
{
int Q;
scanf("%d",&Q);
while(Q--)
{
int val;
scanf("%d",&val);
memset(visited,false,sizeof(visited));
memset(opened,false,sizeof(opened));
DFS(val,0);
int sum=0;
for(int i=1;i<=userNum;i++)
{
if(visited[i]){
sum++;
// printf("i=%d\n",i);
}
}
printf("%d\n",sum-1);
}
}
int main()
{
inti();
work();
return 0;
}
pat1074 最后一组数据有坑,可能有多个-1 导致链表上元素的总数不等于输入的总数
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 100010
struct Node
{
int id;
int address;
int val;
int nextNum;
}node[maxn],node2[maxn];
int firstNum,nodeNum,kNum;
int hashNum[maxn];
int totNum;
bool cmp(Node x,Node y)
{
return x.id<y.id;
}
bool cmp2(Node x,Node y)
{
return x.id>y.id;
}
void inti()
{
memset(hashNum,-1,sizeof(hashNum));
scanf("%d%d%d",&firstNum,&nodeNum,&kNum);
for(int i=1;i<=nodeNum;i++)
{
int address,val,next;
scanf("%d%d%d",&node[i].address,&node[i].val,&node[i].nextNum);
hashNum[node[i].address]=i;
if(node[i].nextNum==-1)hashNum[node[i].nextNum]=-1;
};
totNum=0;
for(int i=hashNum[firstNum];i!=-1;i=hashNum[node[i].nextNum])
{
// printf("i= %d\n",i);
node[i].id=totNum;
node2[totNum++]=node[i];
}
//
// if(k!=nodeNum+1)while(1)k++;
sort(node2,node2+totNum,cmp);
// puts("------------------");
// for(int i=1;i<=nodeNum;i++)printf("%d %d %d %d\n",node[i].id,node[i].address,node[i].val,node[i].nextNum);
// puts("------------------");
}
void work()
{
for(int i=0;i<totNum;i+=kNum)
{
if(i+kNum<=totNum)sort(node2+i,node2+i+kNum,cmp2);
}
for(int i=0;i<totNum-1;i++)node2[i].nextNum=node2[i+1].address;
node2[totNum-1].nextNum=-1;
for(int i=0;i<totNum;i++){
printf("%05d %d ",node2[i].address,node2[i].val);
if(node2[i].nextNum==-1)printf("-1\n");
else printf("%05d\n",node2[i].nextNum);
}
}
int main()
{
inti();
work();
return 0;
}
/*
00100 8 4
00000 4 99999
00100 1 12309
68237 6 89999
33218 3 00000
99999 5 68237
12309 2 33218
89999 8 99996
99996 7 -1
00100 5 4
00000 9 99999
00100 8 12309
33218 1 00000
99999 12 -1
12309 50 33218
00000 1 1
00000 121 -1
*/
pat1047 这题告诉我 char[] 转换成string很耗时间
#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 2555
int n,m;
vector<string>stuCour[maxn];
int main()
{
while(~scanf("%d%d",&n,&m))
{
while(n--)
{
char stuName[20];
int courseNum,courseId;
scanf("%s%d",stuName,&courseNum);
string s=string(stuName);//不要写成stuCour[courseId].push_back(stuName); 否则最后一个案例超时
while(courseNum--)
{
scanf("%d",&courseId);
stuCour[courseId].push_back(s);
}
}
for(int i=1;i<=m;i++)sort(stuCour[i].begin(),stuCour[i].end());
for(int i=1;i<=m;i++)
{
int len=stuCour[i].size();
printf("%d %d\n",i,len);
for(int j=0;j<len;j++)
{
printf("%s\n",stuCour[i][j].c_str());
}
}
}
return 0;
}
另外一种写法 死活都是段错误,代码:
#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<string>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
#define maxn 40040
#define maxm 2555
int n,m;
vector<string>courStu[maxm];
struct ss
{
char name[20];
int cour[440];
int num;
int id;
}stu[maxn];
bool cmp(ss a, ss b)
{
return strcmp(a.name,b.name)<0;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<=n;i++)courStu[i].clear();
for(int i=1;i<=n;i++)stu[i].num=0;
for(int i=1;i<=n;i++)
{
int courseNum,courseId;
scanf("%s%d",stu[i].name,&courseNum);
while(courseNum--)
{
scanf("%d",&courseId);
stu[i].cour[stu[i].num++]=courseId;
}
}
sort(stu+1,stu+n+1,cmp);
for(int i=1;i<=n;i++)
{
string s=string(stu[i].name);
for(int j=0;j<stu[i].num;j++)
{
int t=stu[i].cour[j];
courStu[t].push_back(s);
}
}
for(int i=1;i<=m;i++)
{
printf("%d %d\n",i,courStu[i].size());
for(int j=0;j<courStu[i].size();j++)
{
puts(courStu[i][j].c_str());
}
}
}
return 0;
}
pat1052
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
int hashNum[100010];
struct ss
{
int address;
int val;
int next;
}a[100010],aa[100010];
bool cmp(ss x,ss y)
{
return x.val<y.val;
}
int main()
{
int n,firstadd;
while(~scanf("%d%d",&n,&firstadd))
{
memset(hashNum,-1,sizeof(hashNum));
hashNum[-1]=-1;
for(int i=0;i<n;i++)
{
scanf("%d%d%d",&a[i].address,&a[i].val,&a[i].next);
hashNum[a[i].address]=i;
}
if(firstadd==-1)
{
printf("0 -1\n");
continue;
}
int totNum=0;
for(int i=hashNum[firstadd];i!=-1;i=hashNum[a[i].next])
{
aa[totNum++]=a[i];
}
sort(aa,aa+totNum,cmp);
printf("%d %05d\n",totNum,aa[0].address);
for(int i=0;i<totNum-1;i++)
{
printf("%05d %d %05d\n",aa[i].address,aa[i].val,aa[i+1].address);
}
printf("%05d %d -1\n",aa[totNum-1].address,aa[totNum-1].val);
}
return 0;
}
/*
1 -1
-1 32 -1
*/
pat1029 简单题
#include<iostream>
#include<cstdio>
#define N 1000010
#include<algorithm>
using namespace std;
int a[N],b[N];
int main()
{
int n,m;
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&a[i]);
scanf("%d",&m);
for(int i=0;i<m;i++)scanf("%d",&b[i]);
// sort(a,a+n);
// sort(b,b+m);
int i=0,j=0;
int sum=0;
while(1)
{
sum++;
// printf("* %d %d\n",i,j);
if(a[i]<b[j]&&i<n||j>=m){
if(sum==(n+m+1)/2)
{
printf("%d\n",a[i]);
break;
}
i++;
}
else {
if(sum==(n+m+1)/2)
{
printf("%d\n",b[j]);
break;
}
j++;
}
}
return 0;
}
/*
4 1 2 3 4
5 6 7 8 9 10
5 1 2 3 4 5
4 6 7 8 9
4 1 2 3 4
1 0
*/
pat1024
题意:回文字,对输入数值进行判断,若不是回文,则反转相加继续。
分析:数值10^10,再迭代相加100次,大概达到10^40级;long long型也不足以表示,需要使用字符型处理。使用字符串的reverse处理。
#include <iostream>
#include <string>
#include <algorithm> //reverse函数
using namespace std;
string add(string s,string rev)
{
string res="";
int k = s.size();
int sum,carry=0;
int i;
for(i=k-1;i>=0;i--)
{
sum = s[i]+rev[i]-'0'-'0'+carry;
res.insert(res.begin(),sum%10+'0');
carry = sum/10;
}
if(carry)res.insert(res.begin(),carry+'0');
return res;
}
bool isPalindromic(string& s,string& rev)
{
rev = s;
reverse(rev.begin(),rev.end()); //原字符串反转
if(s==rev) return true;
s = add(s,rev);
return false;
}
int main()
{
string s,rev;
int k;
cin>>s>>k;
int i;
for(i=0;i<k;i++)
{
if(isPalindromic(s,rev))
{
break;
}
}
cout<<s<<endl<<i<<endl;
return 0;
}
pat 1023 注意qsort的用法 (小白书78页)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define ll long long
char a[30],b[30],c[30];
void dou()
{
int k=0,jin=0;
int len=strlen(a);
for(int i=len-1;i>=0;i--)
{
int t=2*(a[i]-'0')+jin;
// printf("a[i]=%c t=%d\n",a[i],t);
b[k++]=t%10+'0';
jin=t/10;
}
if(jin)b[k++]=jin+'0';
b[k]='\0';
for(int i=0;i<k/2;i++){
int t=b[i];
b[i]=b[k-i-1];
b[k-i-1]=t;
}
}
int cmp( const void *_a , const void *_b )
{
char *a=(char* )_a;
char *b=(char* )_b;
return strcmp(a,b);
}
bool isequal()
{
if(strlen(a)!=strlen(c))return false;
int len=strlen(a);
qsort(a,len,sizeof(a[0]),cmp);
qsort(c,len,sizeof(c[0]),cmp);
for(int i=0;i<len;i++){
// printf("** %c %c\n",a[i],c[i]);
if(a[i]!=c[i])return false;
}
return true;
}
int main()
{
while(~scanf("%s",a))
{
dou();
strcpy(c,b);
if(isequal())puts("Yes");
else puts("No");
puts(b);
}
return 0;
}
pat1019 注意n=0的情况就好了
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
int main()
{
int n,b,a[100];
while(~scanf("%d%d",&n,&b))
{
if(n==0){
printf("Yes\n0\n");
continue;
}
int k=0,i;
while(n)
{
a[k++]=n%b;
n/=b;
}
for(i=0;i<k;i++)
{
if(a[i]!=a[k-i-1])break;
}
if(i>=k)puts("Yes");
else puts("No");
for(i=k-1;i>=0;i--){
if(i==0) printf("%d\n",a[i]);
else printf("%d ",a[i]);
}
}
return 0;
}
pat1060 感觉有坑
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
int getk(char *a)
{
int len=strlen(a),i;
for(i=0;i<len;i++)if(a[i]=='.')break;
if(a[0]!='0')return i;
int s=0;
for(i++;i<len;i++){
if(a[i]=='0')s++;
else break;
}
return s;
}
int main()
{
int n;
char a[110],b[110];
while(~scanf("%d%s%s",&n,a,b))
{
int i=0,j=0,ka,kb;
int flag=1;
int lena=strlen(a);
int lenb=strlen(b);
ka=getk(a);
kb=getk(b);
// printf("* %d %d\n",ka,kb);
for(i=0;i<lena;i++){
if(a[i]!='0'&&a[i]!='.')break;
}
for(j=0;j<lenb;j++){
if(b[j]!='0'&&b[j]!='.')break;
}
// printf("++ %d %d\n",i,j);
if(i!=j)flag=0;
else{
while(i<j+n)
{
if(a[i]!=b[i]){
flag=0;
break;
}
i++;
}
}
for(i=0;i<lena;i++){
if(a[i]!='0'&&a[i]!='.')break;
}
for(j=0;j<lenb;j++){
if(b[j]!='0'&&b[j]!='.')break;
}
if(flag){
printf("YES 0.");
while(i<j+n){
printf("%c",a[i]);
i++;
}
printf("*10^%d\n",ka);
}
else {
printf("NO 0.");
int k=i+n;
while(i<k)
{
printf("%c",a[i]);
i++;
}
printf("*10^%d 0.",ka);
k=j+n;
while(j<k)
{
printf("%c",b[j]);
j++;
}
printf("*10^%d\n",kb);
}
}
return 0;
}
/*
3 0.132151 0.000135613
*/
pat1072 两分 T T
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
#define N 1050
#define INF 0x7ffffff
int n,m,k,ds;
int mapp[N][N];
int vis[N],dist[N],pre[N];//dist[N]就记录了从源点到所有其他顶点之间的最短路径长度
char s1[5],s2[5];
int dis;
int getnum(char *a)
{
int i=0,s=0;
if(a[0]=='G')i=1;
for(;i<strlen(a);i++)s=s*10+a[i]-'0';
if(a[0]=='G')return n+s;
else return s;
}
void Dijkstra(int v0)
{
memset(vis,false,sizeof(vis));
for(int i=1;i<=n+m;i++)
{
dist[i]=mapp[v0][i];
if(dist[i]==INF)pre[i]=-1;
else pre[i]=v0;
}
dist[v0]=0;
vis[v0]=true;
int u=v0;
for(int i=2;i<=n+m;i++)//除源点以外的点
{
int min_dist=INF;
// printf("u=%d ",u);
for(int j=1;j<=n+m;j++)
{
if(!vis[j]&&dist[j]<min_dist)
{
u=j;
min_dist=dist[j];
}
}
// printf("v=%d dis=%d\n",u,min_dist);
vis[u]=true;
for(int j=1;j<=n+m;j++)
{
if(!vis[j]&&dist[u]+mapp[u][j]<dist[j])
{
dist[j]=dist[u]+mapp[u][j];
pre[j]=u;
}
}
}
}
int main()
{
while(~scanf("%d%d%d%d",&n,&m,&k,&ds))
{
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)mapp[i][j]=INF;
}
while(k--)
{
scanf("%s%s%d",s1,s2,&dis);
//printf("%d %d\n",getnum(s1),getnum(s2));
mapp[getnum(s1)][getnum(s2)]=dis;
mapp[getnum(s2)][getnum(s1)]=dis;
}
Dijkstra(n+1);
int ansdis=-1,anssum=INF;
bool isok;
for(int i=n+1;i<=n+m;i++)
{
Dijkstra(i);
isok=true;
int sum=0;
int midis=INF;
for(int j=1;j<=n;j++)
{
if(dist[j]>ds)
{
isok=false;
break;
}
if(midis>dist[j])midis=dist[j];
sum+=dist[j];
}
// printf("**%d %d %d %d\n",isok,i,midis,sum);
if(!isok)break;
if(midis>ansdis)
{
ansdis=midis;
anssum=sum;
}
else if(midis==ansdis&&sum<anssum)anssum=sum;
}
if(isok)printf("%d.0 %.1lf\n",ansdis,anssum*1.0/n);
else puts("No Solution");
}
return 0;
}
pat1075 6分 TT
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
struct ss
{
int s[10];
int sum;
int perfect;
int flag;
int id;
}a[10010];
bool cmp(ss x,ss y)
{
if(x.sum==y.sum)
{
if(x.perfect==y.perfect)return x.id<y.id;
return x.perfect>y.perfect;
}
return x.sum>y.sum;
}
int main()
{
int user,pnum,subnum;
int p[10],i,j;
while(~scanf("%d%d%d",&user,&pnum,&subnum))
{
memset(a,-1,sizeof(a));
for(i=0;i<10010;i++)a[i].id=i;
for(i=1;i<=pnum;i++)scanf("%d",&p[i]);
int t,x,y;
while(subnum--){
scanf("%d%d%d",&t,&x,&y);
a[t].s[x]=max(a[t].s[x],y);
if(a[t].s[x]!=-1&&a[t].flag==-1)a[t].flag=1;
}
// puts("pass");
for(i=1;i<=user;i++)
{
if(a[i].flag==0)continue;
a[i].sum=a[i].perfect=0;
for(j=1;j<=pnum;j++)
{
if(a[i].s[j]==-1)continue;
a[i].sum+=a[i].s[j];
if(a[i].s[j]==p[j])a[i].perfect++;
}
}
sort(a+1,a+user+1,cmp);
int ranknum=1,per=1000010,tot=1;
for(i=1;i<=user;i++)
{
if(a[i].flag==-1)continue;
// printf("* per= %d\n",per);
if(a[i].sum<per)
{
per=a[i].sum;
ranknum=tot;
}
printf("%d %05d %d",ranknum,a[i].id,a[i].sum);
for(j=1;j<=pnum;j++)
{
if(a[i].s[j]==-1)printf(" -");
else printf(" %d",a[i].s[j]);
}
// printf(" per=%d",a[i].perfect);
printf("\n");
tot++;
}
}
return 0;
}
pat1055 21/25一直有个案例超时,不知道怎么优化
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 100010
vector<int>Age[220];
struct ss
{
char name[20];
int age;
int rich;
}a[maxn];
vector<ss>tmp;
bool cmp(ss x,ss y)
{
if(x.rich==y.rich)
{
if(x.age==y.age)return strcmp(x.name,y.name)<0;
return x.age<y.age;
}
return x.rich>y.rich;
}
int main()
{
int n,k;
while(~scanf("%d%d",&n,&k))
{
for(int i=0;i<220;i++)Age[i].clear();
for(int i=0;i<n;i++)scanf("%s%d%d",a[i].name,&a[i].age,&a[i].rich);
sort(a,a+n,cmp);
for(int i=0;i<n;i++)
{
Age[a[i].age].push_back(i);
}
int num,x,y;
for(int kk=1;kk<=k;kk++)
{
scanf("%d%d%d",&num,&x,&y);
tmp.clear();
for(int i=x;i<=y;i++)
{
for(int j=0;j<Age[i].size();j++){
tmp.push_back(a[Age[i][j]]);
}
}
sort(tmp.begin(),tmp.end(),cmp);
printf("Case #%d:\n",kk);
int sum=0;
for(int i=0;i<tmp.size();i++)
{
printf("%s %d %d\n",tmp[i].name,tmp[i].age,tmp[i].rich);
sum++;
if(sum==num)break;
}
if(sum==0)puts("None");
}
}
return 0;
}