牛客-PAT历年真题刷题记录(更毕)

本地:F:\nowcoder\pat>
ctrl+f 搜索题目达到指定位置


Public Bike Management (30)
题目链接
题意:0处是管理处,sp处是向管理处报告问题的车站,现要从0处到达sp处,途中路过车站的车辆数目也要调整到M / 2(多的带走继续往下走,少的从0处调拨)
给一个带权图(每个点都是一个车站,0是管理处),从0点出发,到给定的sp车站,求最少花费(最短路),若花费相同,则取从0处调拨的车辆最少的,若0处调拨车辆也相同,则取到达sp车站后,多余的车辆最少的。
思路:数据小,可以直接dfs,不过dijstra会更高效,因为下题与此题类似,dijstra解法下题给出
Code:

#include
#define LL long long 
#define INF 0x3f3f3f3f3f3f3f3f  //途中遇到车不够M/2的马上送过来
using namespace std;
const int AX = 1e3 + 66 ; 
int v[AX] ; 
struct Node{
	int to ; 
	LL w ; 
	Node(){}
	Node( int to , LL w ):to(to),w(w){}
};
vector<Node>G[AX] ;
int M , n , tar , m ;
int vis[AX] ; 
LL minu = INF ;
int ans_s ; //sent
int ans_b ; //back
int pa[AX] ;  
vector<int>res ; 
void get_path( int x ){ 
	while( x != -1 ){
		res.push_back(x);
		x = pa[x] ; 
	}
}
void dfs( int x , LL len , int pre , int sum_s , int sent_b ){
	pa[x] = pre ;
	if( x == tar ){
		if( len < minu || ( len == minu && ans_s > sum_s ) || ( len == minu && ans_s == sum_s && ans_b > sent_b ) ){
			res.clear() ; 
			minu = len ; 
			ans_s = sum_s ;
			ans_b = sent_b ;
			get_path(x);
		}
		return ; 
	}
	for( int i = 0 ; i < G[x].size() ; i++ ){
		int to = G[x][i].to ;
		if( !vis[to] ){
			vis[to] = 1 ;
			int tt = v[to] - M / 2 ;
			dfs( to , len + G[x][i].w , x , sum_s + ( ( v[to] + sent_b < M / 2 ) ? ( M / 2 - v[to] - sent_b ) : 0 ) , max( 0 , sent_b + tt ) );
			vis[to] = 0 ;
		}
	}
}
int main(){
	memset( vis , 0 , sizeof(vis) );
	scanf("%d%d%d%d",&M,&n,&tar,&m);
	for( int i = 1 ;  i <= n ; i++ ){
		scanf("%d",&v[i]);
	}
	int x , y ; LL w ; 
	for( int i = 0 ; i < m ; i++ ){
		scanf("%d%d%lld",&x,&y,&w); 
		G[x].push_back(Node(y,w));
		G[y].push_back(Node(x,w));
	}
	vis[0] = 1 ; 
	dfs( 0 , 0 , -1 , 0 , 0 );
	int size = res.size() ; 
	printf("%d ",ans_s);
	for( int i = size - 1 ; i >= 0 ; i-- ){
		printf("%d",res[i]);
		if( i ) printf("->");
		else printf(" ");		
	}
	printf("%d",ans_b);
	return 0 ; 
}

All Roads Lead to Rome (30)
题目链接
思路:跟上题一样,输出更多些,估计是数据更强的原因,起初写了个dfs超时了1组,改了改800+ms勉强过了,就又写了优先队列实现的dijstra
就是在dijstra算法基础上,增加了
记录最短路径方案数的tot[],
记录每条最短路径节点数的num[],
记录幸福值的ans[],
记录路径的pa[]
每次有更优的最短路径时,全部更新;
若有新的一种最短路径方案时(最短路相等),那么更新方案数为当前节点to方案为tot[to] + tot[u] (u->to) ; 判断幸福值,若更大则更新幸福值与节点数
若幸福值也等,则比较平均幸福值谁大(即比较节点数谁更少)
Code:
dijstra解法

#include 
#define LL long long
using namespace std;
typedef pair<int,int> P ;
const int AX = 2e3 + 666 ;
int n , k ;
map<string,int>mp1;
map<int,string>mp2;
int v[AX];   // node_val
int vis[AX] ;
int pa[AX] ;//path
LL dis[AX]; // cost 
vector<P>G[AX] ;
vector<int>res ;
int tot[AX] ; //solution_number
LL ans[AX] ; // happiness_sum
int num[AX] ; // node_number
void get_path( int x ){
	while( x != -1 ){
		res.push_back(x);
		x = pa[x] ; 
	}
}
void dijstra(){
	priority_queue<P , vector<P> , greater<P> >q;
	q.push(P(0,0));
	dis[0] = 0 ; 
	tot[0] = 1 ; 
	while( !q.empty() ) {
		int u = q.top().second ;
		int val = q.top().first ;
		q.pop();
		if( vis[u] ) continue ;
		vis[u] = 1;
		
		if( val > dis[u] ) continue ; 
		for( int i = 0 ; i < (int)G[u].size() ; i++ ){
			int to = G[u][i].first ; 
			int w = G[u][i].second ;
			if( dis[to] > val + w ){
				
				dis[to] = val + w ; 		// update cost 
				ans[to] = ans[u] + v[to] ;  // update happiness_sum
				tot[to] = tot[u] ;  		// update solution_number 
				num[to] = num[u] + 1 ; 		// update node_number 
				pa[to] = u ;  				// path
				q.push( P( dis[to] , to ) );
			}else if( dis[to] == val + w ){
				tot[to] += tot[u] ; 				// update solution_number
				
				if( ans[to] < ans[u] + v[to] ){
					ans[to] = ans[u] + v[to] ; // update happiness_sum
					num[to] = num[u] + 1 ; 	   // update node_number 
					pa[to] = u ; 			   // update path 
				}else if( ans[to] == ans[u] + v[to] ){
					if( num[to] > num[u] + 1 ){
						num[to] = num[u] + 1 ; // update node_number
						pa[to] = u ; 		   // update path
					}
				}
			}
		}
 	}
}

int main(){
    ios_base::sync_with_stdio(false); cin.tie(0) ;
	int idx = 0 ; 
    string s , b , st ;
    int x ;
    cin >> n >> k ;
    cin >> st ;
    mp1[st] = 0 ;
    mp2[0] = st ;
    for( int i = 1 ; i < n ; i++ ){
        cin >> s >> x ;
		if( !mp1[s] && s.compare(st) ){
			mp1[s] = ++idx ;
			mp2[idx] = s ;
		}
        v[mp1[s]] = x ;
    }
    for( int i = 0 ; i < k ; i++ ){
        cin >> s >> b >> x ;
		int a = mp1[s] , c = mp1[b] ; 
        G[a].push_back(P(c,x));
        G[c].push_back(P(a,x));
    }
    memset( vis , 0 , sizeof(vis) );
	memset( tot , 0 , sizeof(tot) );
	memset( dis , 0x3f , sizeof(dis) );
	memset( ans , 0 , sizeof(ans) );
	memset( num , 0 , sizeof(num) );

	dijstra();
	pa[0] = -1 ; 
	
    int end = mp1["ROM"] ;
    cout << tot[end] << ' ' << dis[end] << ' ' << ans[end] << ' ' << (LL)ans[end] / (LL)num[end] << endl;
	
	get_path(end);
	
    for( int i = res.size() - 1 ; i >= 0 ; i-- ){
        cout << mp2[res[i]] ;
        if( i != 0 ) cout << "->" ;
    }
    return 0 ;
}

dfs解法:

/*得到最小花费后,在最小花费前提下暴搜更新题目要求的最优解,这题dfs稍有不慎就会超时- -。*/
#include 
#define LL long long
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
const int AX = 2e3 + 666 ;
int n , k ;
map<string,int>mp1;
map<int,string>mp2;
int v[AX];
LL minu = INF ; //cost
int vis[AX] ;
int pa[AX] ;
struct Node{
    int to ;
    int w ;
    Node(){}
    Node( int to , int w ):to(to),w(w){}
};
vector<Node>G[AX] ;
vector<int>res , tmp ;
int tot ; //num
LL ans ; //sum_v -> happiness_sum
LL ans_avg ;

void getcost( int x , LL len ){
	if( len > minu ) return ;
	if( x == mp1["ROM"] ){
		minu = min( minu , len );
		return ; 
	}
	for( int i = 0 ; i < G[x].size() ; i++ ){
        int to = G[x][i].to ;
        if( !vis[to] ){
            vis[to] = 1 ;
            getcost( to , len + G[x][i].w );
            vis[to] = 0 ;
        }
    }
}
void dfs( int x , LL len , int pre , int num , LL hap ){
    pa[x] = pre ;
	if( len > minu ) return ; 
    if( x == mp1["ROM"] ){
        if( len == minu ){
			if( hap > ans ){
				ans = hap ;
				ans_avg = hap / (LL)num ;
				res = tmp ; 
			}else if( hap == ans && hap / (LL)num > ans_avg ){
                ans_avg = hap / (LL)num ;
                res = tmp ; 
            }
            tot ++ ;
        }
        return ;
    }
    for( int i = 0 ; i < G[x].size() ; i++ ){
        int to = G[x][i].to ;
        if( !vis[to] ){
            vis[to] = 1 ;
			tmp.push_back(to);
            dfs( to , len + G[x][i].w , x , num + 1 , hap + v[to] );
            vis[to] = 0 ;
			tmp.pop_back();
        }
    }
} 
int main(){
    ios_base::sync_with_stdio(false); cin.tie(0) ;
    tot = 0 ;
	int idx = 0 ; 
    string s , b , st ;
    int x ;
    cin >> n >> k ;
    cin >> st ;
    mp1[st] = 0 ;
    mp2[0] = st ;
    for( int i = 1 ; i < n ; i++ ){
        cin >> s >> x ;
		if( !mp1[s] && s.compare(st) ){
			mp1[s] = ++idx ;
			mp2[idx] = s ;
		}
        v[mp1[s]] = x ;
    }
    for( int i = 0 ; i < k ; i++ ){
        cin >> s >> b >> x ;
		int a = mp1[s] , c = mp1[b] ; 
        G[a].push_back(Node(c,x));
        G[c].push_back(Node(a,x));
    }
    vis[0] = 1 ;
	getcost( 0 , 0 );
	tmp.push_back(0);
    dfs( 0 , 0 , -1 , 0 , 0 );
    
    cout << tot << ' ' << minu << ' ' << ans << ' ' << ans_avg << endl;
	int length = res.size() ; 
    for( int i = 0 ; i < length ; i ++ ){
        cout << mp2[res[i]] ;
        if( i != length - 1 ) cout << "->" ;
    }
    return 0 ;
}

Highest Price in Supply Chain (25)
题目链接
题意:给一个经销商的关系树,并且给出跟经销商的批发价,每下一级都以多卖进价的r%,求最高卖出价钱。
思路:求树的深度,再按题意乘一遍即可
Code:

#include 
using namespace std;
const int AX = 1e5 + 666 ; 
vector<int>v[AX] ;
int lev , num ;  
void get_dep( int x ){
	queue<int>q ;
	q.push(x);
	lev = 0 ; 
	int k = 1 ; 
	while( !q.empty() ){
		int c = 0 ;
		while( k-- ){
			int tmp = q.front() ;
			q.pop();			
			for( int i = 0 ; i < v[tmp].size() ; i++ ){
				q.push(v[tmp][i]);
				c ++ ;
			}
		}
		k = c ;
		lev ++ ; 
		if( c ) num = c ; 
	}
	return ; 
}
int main(){
	int n ;
	double p , r ; 
	int x ; 
	num = 0 ;
	int rt ;
	scanf("%d%lf%lf",&n,&p,&r);
	for( int i = 0 ; i < n ; i++ ){
		scanf("%d",&x);
		if( x == -1 ) rt = i ; 
		else v[x].push_back(i);
	}
	get_dep(rt); 
	if( lev ) lev -- ;
	for( int i = 0 ; i < lev ; i++ ){
		p *= 1.00 + r / 100.0 ; 
	}
	printf("%.2lf %d",p,num);
	return 0 ; 
}

Acute Stroke (30)
题目链接
题意:给一个立体,切成L片,求每个相连的1区域中1个数,计算个数大于t的区域中1个数和。
思路:bfs求连通块,只不过多了一维。

#include 
using namespace std;
int G[2000][200][100];
int vis[2000][200][100] ; 
int dir[6][3] = {
	{ 1 , 0 , 0 },
	{ 0 , 1 , 0 },
	{ 0 , 0 , 1 },
	{ -1 , 0 , 0 },
	{ 0 , -1 , 0 },
	{ 0 , 0 , -1 },
};
struct Node{
	int x , y , z ; 
	Node(){}
	Node( int x , int y , int z ):x(x),y(y),z(z){}
};
int m , n , L , t ;
int res = 0 ;
void bfs( int x , int y , int z ){
	queue<Node>q ; 
	q.push(Node(x,y,z));
	int ans = 1 ;
	vis[x][y][z] = 1 ;
	while( !q.empty() ){
		Node tmp = q.front();
		q.pop();
		for( int i = 0 ; i < 6 ; i++ ){
			int xx = tmp.x + dir[i][0] ;
			int yy = tmp.y + dir[i][1] ;
			int zz = tmp.z + dir[i][2] ;
			if( xx >= 0 && xx < m && yy >= 0 && yy < n && zz >= 0 && zz < L && G[xx][yy][zz] && !vis[xx][yy][zz] ){
				vis[xx][yy][zz] = 1; 
				q.push(Node(xx,yy,zz));
				ans ++ ; 
			}
		}
	}
	if( ans >= t ) res += ans ; 
}
int main(){
	
	scanf("%d%d%d%d",&m,&n,&L,&t);
	for( int k = 0 ; k < L ; k++ ){
		for( int i = 0 ; i < m ; i++ ){
			for( int j = 0 ; j < n ; j++ ){
				scanf("%d",&G[i][j][k]);
			}
		}
	}
	
	for( int k = 0 ; k < L ; k++ ){
		for( int i = 0 ; i < m ; i++ ){
			for( int j = 0 ; j < n ; j++ ){
				if( G[i][j][k] == 1 && !vis[i][j][k] ){
					bfs( i , j , k );
				}
			}
		}
	}
	
	printf("%d",res);
	return 0 ; 
}

The Largest Generation (25)
题目链接
题意:给一个族谱,求哪一代人数最多
思路:树层次遍历,统计每层个数

#include 
using namespace std;
const int AX = 1e2 + 6 ;
int n , m ;   
vector<int>G[AX] ;
int res , num ; 
void get_dep(){
	queue<int>q ;
	q.push(1);
	int k = 1 ; 
	int lev = 0 ;
	while( !q.empty() ){
		int c = 0 ;
		while( k-- ){
			int tmp = q.front() ;
			q.pop();			
			for( int i = 0 ; i < G[tmp].size() ; i++ ){
				q.push(G[tmp][i]);
				c ++ ;
			}
		}
		k = c ;
		lev ++ ; 
		
		if( c > num ){
			num = c ;
			res = lev ; 
		}
	}
	return ; 
}
 
int main(){
	scanf("%d%d",&n,&m);
	int u , v , k ; 
	num = 0 ;
	for( int i = 0 ; i < m ; i++ ){
		scanf("%d%d",&u,&k);
		for( int j = 0 ; j < k ; j++ ){
			scanf("%d",&v);
			G[u].push_back(v) ; 
		}
	}
	get_dep();
	printf("%d %d",num,res+1);
	return 0 ; 
}

Cars on Campus (30)
题目链接

题意:给每个车进入停车场的时间,和离开时间(若一个车只有进没有出 || 只有出没有进 || 不是先进后出,这些都是非法操作直接忽略),进出操作给完后,给出q个询问,输出询问时有几辆车在停车场,最后字母序输出一天内累计停车时间最长的车辆集合,并输出时长
思路:大模拟,样例就看了很久没搞明白,最后才发现是累计时长。
将输入进出停车场排序(相同车辆记录按进出时间早晚排列,不同车辆按车牌字母序排列),然后依次遍历合法操作(先进后出),累加每个车停车最长时间,并且进车时刻车辆++,出车时刻车辆–,遍历完后对每个时刻车辆数做前缀和,得出每个时刻的车辆数,询问时直接输出。最后遍历停车时长等于最大时长的车辆输出即可。

/*有in没有out的忽略,out在in前的忽略*/
#include  
using namespace std;
const int AX = 1e5 + 666 ; 
const int MAX = 24 * 3600 + 60 * 60 + 60 ;
map<string,int>last ;
struct Node{
	char c[10] ;
	int t ; 
	int sta ; 
	bool operator < ( const Node &x )const{
		if( !strcmp( c , x.c ) ) return t < x.t ; 
		return strcmp(c,x.c) < 0 ;  
	}
}a[10005];
int cal( int h , int m , int s ){
	return h * 3600 + m * 60 + s ; 
}
void print( int x ){
	int base = 3600 ; 
	for( int i = 0 ; i < 3 ; i++ ){
		int tt = x / base ; 
		if( tt < 10 ) printf("0%d",tt);
		else printf("%d",tt);
		if( i != 2 ) printf(":"); 
		x %= base ; 
		base /= 60 ;
	}
}
int maxn ;
int te[AX] ; //一辆车一天停车的累计时间
int main(){
	int n , q ; 
	int h , m , s ; 
	char op[5] ;  
	maxn = 0 ;
	scanf("%d%d",&n,&q);
	for( int i = 0 ; i < n ; i++ ){
		scanf("%s%d:%d:%d%s",a[i].c,&h,&m,&s,op);
		a[i].t = cal(h,m,s) ;
		a[i].sta = (op[0]=='o') ; // in 0 , out 1 
	}
	sort( a , a + n );
	maxn = 0 ;
	memset( te , 0 , sizeof(te) ) ;
	for( int i = 0 ; i < n - 1 ; i++ ){
		if( !strcmp( a[i].c , a[i+1].c ) ){
			if( !a[i].sta && a[i+1].sta ){
				last[a[i].c] += ( a[i+1].t - a[i].t );
				te[a[i].t] ++ ;
				te[a[i+1].t] -- ;
			}
		}
		maxn = max( maxn , last[a[i].c] );
	}
	for( int i = 1 ; i < MAX ; i++ ){
		te[i] += te[i-1] ;
	}
	while( q-- ){
		scanf("%d:%d:%d",&h,&m,&s);
		int tmp = cal(h,m,s);
		printf("%d\n",te[tmp]);
	}
	for( auto tt : last ){
		if( maxn == tt.second ){
			printf("%s ",tt.first.c_str());
		}
	}
	print(maxn);
	return 0 ; 
}

Consecutive Factors (20)
题目链接

思路:求出所有因子,枚举连续因子的最小因子。

#include 
using namespace std;
int tot ; 
set<int>s;
void get_fac( int x ){
	int len = sqrt(x) + 1 ; 
	for( int i = 2 ; i < len ; i++ ){
		if( x % i == 0 ){
			s.insert(i);
			if( x / i > 1 ) s.insert( x / i );
		}
	}
	s.insert(x);
}
int main(){
	int n ;
	cin >> n ; 
	tot = 0 ;
	get_fac(n);
	int res = 1 ;
	int st = *s.begin(); 
	for( auto i : s ){
		int tmp = n ; 
		int ans = 0 ;
		int t = i ; 
		while( tmp > 0 && tmp % t == 0 ){
			tmp /= t ;
			t ++ ;
			ans ++ ; 
		}
		if( res < ans ){
			res = ans ;
			st = i ;
		}
	}
	cout << res << endl;
	for( int i = st ; i < st + res ; i++ ){
		printf("%d",i);
		if( i != st+res-1 ) printf("*");
	}
}

Deduplication on a Linked List (25)

#include 
using namespace std;
const int AX = 1e5 + 666 ;
struct Node{
	int ad ;
	int v ;
	int nxt ; 
}a[AX] ;
vector<Node>res1 ;
vector<Node>res2 ;
int main(){
	int n ;
	map<int,int>mp ;
	int adr ; 
	int st ; 
	scanf("%d%d",&st,&n);
	for( int i = 0 ; i < n ; i++ ){
		scanf("%d",&adr);
		scanf("%d%d",&a[adr].v,&a[adr].nxt);
		a[adr].ad = adr ; 
	}
	int tmp = st ;  
	while( tmp != -1 ){
		if( !mp[abs(a[tmp].v)] ){
			mp[abs(a[tmp].v)] = 1 ;
			res1.push_back(a[tmp]);
		}else{
			res2.push_back(a[tmp]);
		}
		tmp = a[tmp].nxt ; 
	}
	int len = res1.size();
	for( int i = 0 ; i < len - 1 ; i ++ ){
		printf("%05d %d %05d\n",res1[i].ad,res1[i].v,res1[i+1].ad);
	}
	printf("%05d %d -1\n",res1[len-1].ad,res1[len-1].v);
	
	len = res2.size();
	for( int i = 0 ; i < len - 1 ; i ++ ){
		printf("%05d %d %05d\n",res2[i].ad,res2[i].v,res2[i+1].ad);
	}
	printf("%05d %d -1",res2[len-1].ad,res2[len-1].v);
	return 0 ; 
}
  1. Insertion or Heap Sort (25)
    题意:给两个序列,一个是原始序列,另一个是经过部分排序步骤的,要求判断是插入排序还是堆排序,并且输出下一趟排序序列
    思路:根据堆排序 升序序列是大顶堆,那么判断数组是否满足大顶堆性质(i的儿子2i,2i+1都小于i的节点值),如果满足则为堆排序,调整堆一次即可;如果不满足,则为插入排序,就简单了,直接从前往后找不满足顺序性质的往前插即可。
/*检查大顶堆性质判断是否为堆排序,是就找出末尾位置,调整一次,不是就插入排序来一次*/
#include 
using namespace std ;
const int AX = 1e2 + 66 ; 
int a[AX] ; 
int b[AX] ;
int n ;
void print(){
	for( int i = 1 ; i <= n ; i++ ){
		printf("%d",b[i]);
		if( i < n ) printf(" ");
	}
}
void adjust_heap( int len ){
	int i = 1 ; 
    int temp = b[i] ;
	for( int k = i * 2 ; k < len ; k *= 2 ){
		if( k + 1 < len && b[k] < b[k+1] ) k ++ ;
		if( b[k] > temp ){
			b[i] = b[k];
			i = k ;
		}else break ;
    }
	b[i] = temp ;
}
int main(){
	scanf("%d",&n);
	for( int i = 1 ; i <= n ; i++ ){
		scanf("%d",&a[i]);
	}
	for( int i = 1 ; i <= n ; i++ ){
		scanf("%d",&b[i]);
	}
	int f = 1 ; 
	sort( a + 1 , a + n + 1 ) ;
	int k = n ; 
	while( k > 0 && a[k] == b[k--] ) ; //找堆顶与每次调整后的末尾元素交换次数,即后几个元素排好序了
	k ++ ; 
	for( int i = 1 ; i <= n ; i++ ){
		int x = 2 * i ; 
		int y = x + 1 ;
		if( ( x < k && b[i] < b[x] ) || ( y < k && b[i] < b[y] ) ){ // 检查大顶堆->升序
			f = 0 ; break ; 
		}
	}
	if( f ){
		printf("Heap Sort\n");
		swap( b[1] , b[k] );
		adjust_heap(k);
		print();
	}else{
		printf("Insertion Sort\n");
		for( int i = 2 ; i <= n ; i++ ){
			if( b[i] < b[i-1] ){
				while( i > 1 && b[i] < b[i-1] ){
					swap( b[i] , b[i-1] );
					i -- ; 
				}
				break ; 
			}
		}
		print();
	}
	return 0 ; 
}

Build A Binary Search Tree (30)
思路:按题意,中序建树,层次遍历输出即可

#include 
using namespace std;
const int AX = 1e2 + 66 ;
vector<int>G[AX] ; 
int a[AX] ;
int tot ;
map<int,int>mp;
vector<int>res; 
void in_order( int rt ){
	if( rt == -1 ) return ;  
	in_order( G[rt][0] );
	mp[rt] = a[tot++] ; 
	in_order( G[rt][1] );
}

void lev_order(){
	queue<int>q ;
	q.push(0);
	while( !q.empty() ){
		int tmp = q.front();
		q.pop();
		res.push_back(mp[tmp]);
		if( G[tmp][0] != -1 ) q.push(G[tmp][0]);
		if( G[tmp][1] != -1 ) q.push(G[tmp][1]);
	}
}
int main(){
	int n ;
	tot = 0 ;	
	scanf("%d",&n);
	int l , r ; 
	for( int i = 0 ; i < n ; i++ ){
		scanf("%d%d",&l,&r);
		G[i].push_back(l);
		G[i].push_back(r);
	}
	for( int i = 0 ; i < n ; i++ ){
		scanf("%d",&a[i]);
	}
	sort( a , a + n ) ;
	in_order(0);
	lev_order();
	int len = res.size() ; 
	for( int i = 0 ; i < len ; i++ ){
		printf("%d",res[i]);
		if( i != len - 1 ) printf(" ");
	}
	return 0 ; 
}

Forwards on Weibo (30)
题意:求一个节点有几个深度小于L的后代节点
思路:直接dfs

#include 
using namespace std ;
const int AX = 1e3 + 66 ;
int n , L , k , x , res ; 
vector<int>v[AX] ;
int vis[AX] ;
void dfs( int x , int pre , int dep ){
	if( dep > L ) return ;
	vis[x] = 1; 
	for( int i = 0 ; i < v[x].size() ; i++ ){
		if( x != pre ) dfs( v[x][i] , x , dep + 1 );
	}
}
int main(){
	scanf("%d%d",&n,&L);
	for( int i = 1 ; i <= n ; i++ ){
		scanf("%d",&k);
		while( k-- ){
			scanf("%d",&x);
			v[x].push_back(i);
		}
	}
	scanf("%d",&k);
	while( k-- ){
		scanf("%d",&x);
		res = 0 ;
		memset( vis , 0 , sizeof(vis) ) ;
		dfs( x , -1 , 0 );
		for( int i = 1 ; i <= n ; i++ ){
			if( vis[i] ) res ++ ;
		}
		printf("%d\n",res - 1 );
	}
	return 0 ;
}

Kuchiguse (20)

#include 
using namespace std ;
const int AX = 1e2 + 66 ;
string s[AX] ;
int a[AX][AX] ; 
int main(){
	//ios_base::sync_with_stdio(false); cin.tie(0);
	int n;
	cin >> n ; 
	getchar();
	for( int i = 0 ; i < n ; i++ ){
		getline(cin,s[i]); 
		reverse( s[i].begin() , s[i].end() );
	}
	int res = 0 ;
	for( int i = 0 ; i < s[0].size() ; i++ ){
		int f = 1 ;
		for( int j = 0 ; j < n ; j ++ ){
			if( s[j][i] != s[0][i] ){ f = 0 ; break ; }
		}
		if( !f ) break ;
		res ++ ; 
	}
	string ans = "" ; 
	for( int i = 0 ; i < res ; i++ ){
		ans += s[0][i] ;
	}
	reverse( ans.begin() , ans.end() );
	if(res) cout << ans ; 
	else cout << "nai" ;
	return 0 ;
}

Hashing (25)

#include 
using namespace std;
const int AX = 1e5 ;
int tot ;  
vector<int>p;
map<int,int>mp;
void get_prime(){
	p.push_back(2);
	for( int i = 3 ; i <= AX ; i++ ){
		int j ; 
		int len = sqrt(i) + 1 ;
		for( j = 2 ; j <= len ; j++ ){
			if( i % j == 0 ) break ; 
		}
		if( j <= len ) continue ; 
		p.push_back(i);
	}
}

int main(){
	int n , m , x ;
	get_prime();
	scanf("%d%d",&n,&m) ;
	mp.clear() ; 
	int pos = lower_bound( p.begin() , p.end() , n ) - p.begin() ;
	n = p[pos] ; 
	while( m-- ){
		scanf("%d",&x);
		int j ;
        for( j = 0 ; j < n ; j++ ){
            int tmp = ( x +  j * j ) % n ;    
            if( !mp[tmp] ){
                mp[tmp] = 1;
                printf("%d",tmp);
                break;
            }
        }
		if( j == n ) printf("-");
		if( m ) printf(" ");
	}
	return 0 ;
}

Total Sales of Supply Chain (25)

#include 
using namespace std ;
const int AX = 1e5 + 666 ; 
double v[AX] ; 
vector<int>G[AX] ; 
double res ; 
int n ; 
double p , r ;
map<int,int>mp;
void dfs( int x , int dep ){
	
	if( mp[x] ){
		double ans = p ; 
		for( int i = 0 ; i < dep ; i++ ){
			ans *= (1+r) ;
		}
		ans *= v[x] ;
		res += ans ; 
		return ; 
	}
	for( int i = 0 ; i < G[x].size() ; i++ ){
		int to = G[x][i] ; 
		dfs( to , dep + 1 );
	}
}

int main(){
	int x , k ; 
	scanf("%d%lf%lf",&n,&p,&r);
	r /= 100.0 ; 
	for( int i = 0 ; i < n ; i++ ){
		scanf("%d",&k);
		if( !k ) { mp[i] = 1 ; scanf("%lf",&v[i]) ; }
		for( int j = 0 ; j < k ; j++ ){
			scanf("%d",&x);
			G[i].push_back(x);
		}
	}
	res = 0.0 ; 
	dfs( 0 , 0 );
	printf("%.1lf",res);
	return 0  ;
}

Graduate Admission (30)

题意:n个学生可以填k个志愿,m个学校有quota个招生名额,学生优先考虑第一志愿,不录取则顺延后面志愿,学校按照ge+gi成绩排名,如果相同,则按ge排名,如果一个学校录取了x同学,并且有y同学和x同学两个成绩相同,则即是名额不够也都要录取,求最后的录取名单

思路:将学生成绩降序排序,访问完每个人的k个志愿(分高的先挑学校)再继续下个人,
如果第j志愿有名额,直接录取;
如果第j志愿没有名额了就看看这个学校(第j志愿)有没有招收两项成绩都跟自己相同的,有自己就被录取。

#include 
using namespace std;
const int AX = 4e4 + 6 ;
int n , m , k ;
int quota[105] ;
struct Node {
	int ge , sum ;
	int id ;
	int zy[6] ;
	bool operator < ( const Node &a )const {
		if( sum == a.sum ) return ge > a.ge ;
		return sum > a.sum ;
	}
} st_g[AX] ;

map<int,int>ID;
vector<Node>st ;
vector<int>res[105] ;

int main() {
	scanf("%d%d%d",&n,&m,&k);
	for( int i = 0 ; i < m ; i++ ) {
		scanf("%d",&quota[i]);
	}
	int x ;
	for( int i = 0 ; i < n ; i++ ) {
		scanf("%d%d",&st_g[i].ge,&x);
		st_g[i].id = i ;
		st_g[i].sum = x + st_g[i].ge ;
		for( int j = 0 ; j < k ; j++ ) {
			scanf("%d",&x);
			st_g[i].zy[j] = x ;
		}
		st.push_back(st_g[i]);
	}
	sort( st.begin() , st.end() );
	for( int i = 0 ; i < n ; i++ ) {
		ID[st[i].id] = i ;
	}
	for( int i = 0 ; i < n ; i++ ) {
		for( int j = 0 ; j < k ; j++ ) {
			int zy = st[i].zy[j] ;
			if( quota[zy] > 0 ) {
				quota[zy] -- ;
				res[zy].push_back(st[i].id);
				break ;
			} else {
				int kk = res[zy].size() - 1 ;
				if( st[ID[res[zy][kk]]].sum == st[i].sum && st[i].ge == st[ID[res[zy][kk]]].ge ) {
					quota[zy] -- ;
					res[zy].push_back(st[i].id) ;
					break ;
				}
			}
		}
	}
	for( int i = 0 ; i < m ; i++ ) {
		sort( res[i].begin() , res[i].end() );
		if( !res[i].size() ) printf("\n");
		else {
			int len = res[i].size() ;
			for( int j = 0 ; j < len ; j++ ) {
				printf("%d",res[i][j]);
				if( j != len - 1 ) printf(" ");
			}
			if( i != m - 1 ) printf("\n");
		}
	}
	return 0 ;
}


Mice and Rice (25)

#include 
using namespace std ;
const int AX = 1e3 + 66 ;
int a[AX] ; 
vector<int>t;
int lev[AX] ; 
struct Node{
	int id ;
	int v ;
	Node(){}
	Node( int id , int v ):id(id),v(v){}
	bool operator < ( const Node &b )const{
		return v < b.v ; 
	}
};
int main(){
	int n , k ; 
	scanf("%d%d",&n,&k);
	for( int i = 0 ; i < n ; i++ ){
		scanf("%d",&a[i]);
	}
	int x ; 
	for( int i = 0 ; i < n ; i++ ){
		scanf("%d",&x);
		t.push_back(x);
	}
	
	vector<int>tmp ; 
	while( t.size() > 1 ){
		int len = t.size() ; 
		for( int i = 0 ; i < len ; i += k ){
			priority_queue<Node>q ;
			int num = len / k + ( len % k != 0 );
			for( int j = i ; j < min( i + k , len ) ; j++ ){
				q.push(Node(t[j],a[t[j]]));
			}
			tmp.push_back(q.top().id);
			q.pop();
			while( !q.empty() ){
				lev[q.top().id] = num + 1 ;
				q.pop();
			}
		}
		t.clear();
		t.assign(tmp.begin(),tmp.end());
		tmp.clear();
	}
	lev[t[0]] = 1 ;
	for( int i = 0 ; i < n ; i ++ ){
		printf("%d",lev[i]);
		if( i != n - 1 ) printf(" ");
	}
	return 0 ; 
}

Stack (30)
树状数组(单点更新,区间查询)+二分
进出栈就存储在正常的栈里面,同时将数值x插入到树状数组相应x位置,点值更新+1,
查询中位数时就二分位置,如果这个位置前的区间有ans个数且ans>=id(id=(元素数量+1)/2),则满足

#include 
using namespace std;
const int AX = 1e5 + 66 ;
int c[AX] ; 
int lowbit( int x ){
	return x & (-x) ; 
}
void update( int x , int v ){
	while( x <= AX ){
		c[x] += v ; 
		x += lowbit(x);
	}
}
int querry( int x ){
	int ans = 0 ;
	while( x ){
		ans += c[x] ;
		x -= lowbit(x) ; 
	}
	return ans ; 
}

int main() {
	int n ;
	char op[20] ;
	scanf("%d",&n) ;
	stack<int>s ;
	int x ;
	for( int i = 0 ; i < n ; i++ ) {
		scanf("%s",op);
		if( op[1] == 'u' ) { //push
			scanf("%d",&x);
			s.push(x);
			update( x , 1 ) ;
		}
		int len = s.size() ;
		if( !len ) {
			printf("Invalid\n");
			continue ;
		}
		if( op[1] == 'o' ) { //pop
			printf("%d\n",s.top());
			update( s.top() , -1 );
			s.pop();
		}
		if( op[1] == 'e' ) { //peekMedian
			int l = 0 , r = AX ;
			int id = ( s.size() + 1 ) >> 1 ; 
			while( l <= r ){
				int mid = ( l + r ) >> 1 ; 
				if( querry(mid) >= id ) r = mid - 1 ;
				else l = mid + 1 ;
			}
			printf("%d\n",l) ;
		}
	}
	return 0 ;
}

A+B in Hogwarts (20)

#include 
using namespace std;
int main(){
	int a, b, c, d, e, f ;
	scanf("%d.%d.%d",&a,&b,&c);
	scanf("%d.%d.%d",&d,&e,&f);
	int up = 0 ;
	c += f ; 
	up = c / 29 ;
	c %= 29 ;
	b += e + up ; 
	up = b / 17 ;
	b %= 17 ; 
	a += d + up ;
	printf("%d.%d.%d",a,b,c);
	return 0 ; 
}

Prime Factors (25)

#include 
#define LL long long 
using namespace std;
set<LL>res ; 
map<LL,int>mp ;
void get_prime_factor( LL x ){
	for( LL i = 2 ; i * i <= x ; i++ ){
		if( x % i == 0 ){
			res.insert(i);
			while( x % i == 0 ){
				x /= i ;
				mp[i] ++ ; 
			}
		}
	}
	if( x > 1 ){ res.insert(x); mp[x] ++ ;}
}
int main(){
	LL n ;
	mp.clear();
	scanf("%lld",&n);
	if( n == 1 ){
		printf("1=1\n");
		return 0 ;
	}
	get_prime_factor(n);
	printf("%lld=",n);
	int len = res.size() ; 
	set<LL>::iterator it = res.begin() ; 
	for( int i = 0 ; i < len ; i++,it++ ){
		printf("%lld",(*it));
		if( mp[(*it)] > 1 ) printf("^%d",mp[(*it)]);
		if( i != len - 1 ) printf("*"); 
	}
	return 0 ; 
}

Are They Equal (25)

#include 
using namespace std;
int n ;	
int get_int_num( string a ){
	int ans = 0 ;
	for( int i = 0 ; i < a.size() ; i++ ){
		if( a[i] == '.' ) break ; 
		ans ++ ; 
	}
	return ans ; 
}
string get_s( string s , int ints ){
	string ans ; 
	
	int len = s.size() ; 
	if( len > 1 && s[0] == '0' && s[1] == '.' ){ // 0.b
		ans += "0." ;
		int f = 0 ;
		int tot = 0 ;
		int tt = 0 ;
		for( int i = 2 ; i < len && tot < n ; i++ ){
			if( !f && s[i] == '0' ){ tt++ ; continue ; }
			f = 1 ;
			tot ++ ;
			ans += s[i] ; 
		}
		if( tot < n ){
			for( int i = 0 ; i < n - tot ; i++ ){
			//	cout << "0" ;
				ans += "0" ; 
			}
		}
		if( !f ) tt = 0 ;
		ans += "*10^" ;
		if( tt ) ans += "-" ; 
		stringstream ss ;
		string tmp ; 
		ss << tt ; 
		ss >> tmp ;
		ans += tmp;
		
	}else{
		//cout << "0." ;
		ans += "0." ; 
		int tot = 0 ;
		int j = 0 ;
		int ff = 0 ;
		while( j < len && s[j] == '0' ){ ff ++ ; j ++ ; } //前导0 -> 000a.b , 00000a
		for( ; j < len && tot < n ; j++ ){
			if( s[j] != '.' ){  // a.b or a
				//cout << s[j] ; 
				ans += s[j] ;
				tot ++ ;
			}
		}
		if( tot < n ){
			for( int i = 0 ; i < n - tot ; i++ ){
			//	cout << "0" ;
				ans += "0" ; 
			}
		}
		//cout << "*10^" << ints ;
		if( !ff && s[0] == '0' ) ints = 0 ;
		if( ff ) ints -= ff ;  
		ans += "*10^" ;
		stringstream ss ;
		string tmp ; 
		ss << ints ; 
		ss >> tmp ;
		ans += tmp;
	}		
	return ans ; 
}
int main(){
	string a , b ; 
	cin >> n ;
	cin >> a >> b ; 
	int inta , intb ;
	inta = get_int_num(a);
	intb = get_int_num(b);
	string sa = get_s(a,inta);
	string sb = get_s(b,intb);
	if( !sa.compare(sb) ){
		cout << "YES " << sa ; 
	}else{
		cout << "NO " << sa << ' ' << sb ; 
	}
	return 0 ; 
}

Set Similarity (25)
题意:交集/并集

#include 
using namespace std;
typedef pair<int,int>P;
const int AX = 50 + 6 ;
set<int>s[AX];
map<int,int>mp ;
int main() {
	int n , m , x , y ;
	scanf("%d",&n);
	for( int i = 1 ; i <= n ; i++ ) {
		scanf("%d",&m);
		while( m-- ) {
			scanf("%d",&x);
			s[i].insert(x);
		}
	}

	int q ;
	scanf("%d",&q);
	while( q-- ) {
		scanf("%d%d",&x,&y);
		mp.clear();
		if( x == y ) {
			printf("100.0%\n");
			continue ;
		}
		int nc = 0 ;
		for( auto i : s[x] ){
			if( s[y].count(i) ) nc ++ ;
		}
		int nt = s[x].size() + s[y].size() - nc ; 
		printf("%.1lf\%\n",(double)nc/(double)nt*100.0);
	}
	return 0 ;
}

Complete Binary Search Tree (30)

/*完全二叉树父节点i与子节点关系(左2*i,右2*i+1),BST中序为有序序列*/
#include 
using namespace std;
const int AX = 1e3 + 666 ;
int a[AX] ; 
int res[AX] ; 
int n , tot ;
void build( int rt ){
	if( rt > n ) return ;  
	build( rt * 2 ) ;
	res[rt] = a[tot++] ;
	build( rt * 2 + 1 ) ; 
}

int main(){
	scanf("%d",&n);
	tot = 0 ;
	for( int i = 0 ; i < n ; i++ ){
		scanf("%d",&a[i]);
	}
	sort( a , a + n ) ;
	build(1);
	for( int i = 1 ; i <= n ; i++ ){
		printf("%d",res[i]);
		if( i != n ) printf(" ");
	}
	return 0 ; 
}

A+B and C (64bit) (20)

#include 
using namespace std;
int main(){
	int T ;
	cin >> T ;
	long long a , b , c ; 
	int test = 0 ; 
	while( T-- ){
		cout << "Case #" << ++test << ": " ; 
		cin >> a >> b >> c ; 
		int f = 0 ;
		
		long long ans = a + b  ;
		if( a > 0 && b > 0 && ans <= 0 ) f = 0 ;
		else if( a < 0 && b < 0 && ans >= 0 ) f = 1 ;
		else f = ( ans <= c ) ; 
		cout << ( f ? "false" : "true" ) << endl;
	}
	return 0 ; 
}

Sort with Swap(0,*) (25)

/*找位置不对的环,若环中有0,则交换次数是环节点数-1,
若没有0,则环节点数-1+2(需要用0换,+2是用0凑,将0换进环来再换出去)*/
#include 
using namespace std;
const int AX = 1e5 + 666 ;
int n ;
int a[AX] , vis[AX] ; 
int tot , zero ; 
map<int,int>mp;
void dfs( int x ){
	if( vis[x] ) return ; 
	if( !x ) zero = 1 ;
	vis[x] = 1 ; 
	tot ++ ; 
	dfs( mp[x] );
}
int main(){
	scanf("%d",&n);
	memset( vis, 0 , sizeof(vis) ) ;
	for( int i = 0 ; i < n ; i++ ){
		scanf("%d",&a[i]);
		mp[a[i]] = i ; 
	}
	int res = 0;
	for( int i = 0 ; i < n ; i++ ){
		if( a[i] != i && !vis[a[i]] ){
			tot = 0 , zero = 0 ;
			dfs(i);
			if( zero ) res += ( tot - 1 ) ; 
			else res += ( tot - 1 + 2 ) ; 
		}
	}
	printf("%d",res);
	return 0 ; 
}

Find More Coins (30)
思路:k很小,直接dfs

#include 
using namespace std;
int n , k , x ;
vector<int>res;
vector<int>tmp;
map<int,int>mp;
int f ;
void dfs( int m ) {
	if( f ) return ; 
	if( !m ) {
		f = 1 ; 
		res = tmp ; 
		return ; 
	}
	for( auto i : mp ) {
		if( i.second ) {
			if( m >= i.first ) {
				mp[i.first] --; 
				tmp.push_back(i.first);
				dfs( m - i.first );
				tmp.pop_back();
				mp[i.first] ++; 
			}
		}
	}
}
int main() {
	scanf("%d%d",&n,&k);
	for( int i = 0 ; i < n ; i++ ) {
		scanf("%d",&x);
		if( x <= k ) mp[x] ++ ;
	}
	f = 0 ;
	dfs(k);
	if( !res.size() ) return 0*printf("No Solution");
	int len = res.size();
	for( int i = 0 ; i < len ; i++ ){
		printf("%d",res[i]);
		if( i != len - 1 ) printf(" ");
	}
	return 0 ;
}
  1. Speech Patterns (25)
#include 
using namespace std;
map<string,int>mp ;
bool check( char ch ) {
	return ( ( ch >= '0' && ch <= '9' ) || ( ch >= 'a' && ch <= 'z' ) || ( ch >= 'A' && ch <= 'Z' ) ) ;
}
int ans ;
int main() {
	ans = 0 ;
	string s ;
	getline( cin , s );
	string tmp ;
	for( int i = 0 ; i < s.size() ; i ++ ) {
		if( s[i] >= 'A' && s[i] <= 'Z' ) s[i] = s[i] - 'A' + 'a' ;
		if( !check(s[i]) ) {
			if( !tmp.size() ) continue ; 
			mp[tmp] ++ ;
			if( ans < mp[tmp] ) {
				ans = mp[tmp] ;
			}
			tmp = "" ;
		} else tmp += s[i] ;
	}
	if( tmp.size() ) {
		mp[tmp] ++ ;
		if( ans < mp[tmp] ) {
			ans = mp[tmp] ;
		}
	}
	for( auto i : mp ){
		if( i.second == ans ){
			cout << i.first << ' ' ;
			break ; 
		}
	}
	cout << ans ;
	return 0 ;
}

Gas Station (30)

/*
题意:给定m个站,选择其中最优的一个,要求其到各个居民区的最短距离 最长,
若有多个解,则选择平均长度小的,仍有多个,则选择索引小的,另外要求最长距离不能超过Gi站的覆盖范围
思路:dijstra求每个Gi到居民区各点的最短路,按要求取最优结果即可,注意结果四舍五入保留一位小数。
 
这样还是蛮快的10ms,排在50多位
*/
#include 
#define INF 0x3f3f3f3f3f3f3f3f
#define LL long long 
using namespace std;
typedef pair<LL,int>P;
const int AX = 1e3 + 666 ;
int n , m , k ;
LL D ;
LL minu ; 
LL avg ; 
struct Node {
	int to ;
	LL w ;
	Node() {}
	Node( int to , int w ):to(to),w(w) {}
};
vector<P>G[AX] ;
int vis[AX] ;
LL dis[AX] ;
void dijstra( int st ) {
	priority_queue<P,vector<P>,greater<P> >q ;
	q.push(P(0,st));
	dis[st] = 0 ;
	while( !q.empty() ) {
		int u = q.top().second;
		LL val = q.top().first ;
		q.pop();
		if( vis[u] ) continue ;
		vis[u] = 1 ;

		if( val > dis[u] ) continue ;
		for( int i = 0 ; i < (int)G[u].size() ; i++ ) {
			int to = G[u][i].second ;
			LL w = G[u][i].first ;
			if( val + w < dis[to] ) {
				dis[to] = val + w ;
				q.push(P(dis[to],to));
			}
		}
	}
}
int main() {
	int x , y ;
	LL w ; 
	int id ; 
	char p1[10];
	char p2[10];
	minu = -1  ; 
	scanf("%d%d%d%lld",&n,&m,&k,&D);
	while( k-- ) {
		scanf("%s%s%lld",&p1,p2,&w);
		
		if( p1[0] == 'G' ) x = atoi(p1+1) + n ;
		else x = atoi(p1);
		if( p2[0] == 'G' ) y = atoi(p2+1) + n ;
		else y = atoi(p2);
		
		G[x].push_back(P(w,y));
		G[y].push_back(P(w,x));
	}
	for( int i = 1 ; i <= m ; i++ ) {
		memset( dis , 0x3f , sizeof(dis) );
		memset( vis , 0 , sizeof(vis) );
		dijstra(i+n);
		int f = 1 ;
		LL ans = INF ;
		LL sum = 0 ; 
		for( int j = 1 ; j <= n ; j++ ){
			if( dis[j] > D ){ f = 0 ; break ; }
			ans = min( ans , dis[j] );
			sum += dis[j] ; 
		}
		if( !f ) continue ; 
		if( ans > minu ){
			id = i ; 
			minu = ans ; 
			avg = sum  ;
		}else if( ans == minu ){
			if( avg > sum ){
				id = i ; 
				avg = sum ; 
			}
		}
	}
	if( minu != -1 ){
		printf("G%d\n",id);
		int tmp = ((double)avg/(double)n + 0.05)*10 ;//四舍五入保留一位小数
		printf("%.1lf %.1lf",(double)minu,(double)tmp/10.0);
	}else{
		printf("No Solution");
	}
	return 0;
}

Be Unique (20)

#include 
using namespace std;
const int AX = 1e5 + 66 ;
int a[AX] ; 
int main(){
	int n ; 
	scanf("%d",&n);
	map<int,int>mp ;
	for( int i = 0 ; i < n ; i++ ){
		scanf("%d",&a[i]);
		mp[a[i]] ++ ; 
	}
	for( int i = 0 ; i < n ; i++ ){
		if( mp[a[i]] == 1 ){
			return 0*printf("%d",a[i]);
		}
	}
	printf("None");
	return 0  ;
}

Shuffling Machine (20)
题意:给定原来的牌的序列,要求按照给定操作将第i张牌放到a[i]处,重复执行一定次数,求最终的序列

#include 
using namespace std;
vector<string>a ;
vector<string>b ;
vector<int>c ;
char s[5] = { 'S' , 'H' , 'C' , 'D' } ; 
void init(){
	for( int i = 0 ; i < 4 ; i++ ){
		string tmp = "" ;
		tmp = s[i] ; 
		for( int j = 1 ; j <= 13 ; j++ ){
			char str[5] ; 
			sprintf(str,"%d",j);
			tmp += (string)str ;
			a.push_back(tmp);
			b.push_back(tmp);
			tmp = s[i] ; 
		}
	}
	a.push_back("J1");
	a.push_back("J2");
	b.push_back("J1");
	b.push_back("J2");
}
int main(){
	int k , x ;  
	init();
	cin >> k ;
	for( int i = 0 ; i < 54 ; i++ ){
		cin >> x ; 
		c.push_back(x);
	}
	while( k-- ){
		for( int i = 0 ; i < c.size() ; i++ ){
			b[c[i]-1] = "" ; 
			b[c[i]-1] += a[i] ; 
		}
		for( int i = 0 ; i < 54 ; i++ ){
			a[i] = "" ; 
			a[i] += b[i] ; 
		}
	}
	for( int i = 0 ; i < 54 ; i++ ){
		cout << a[i] ;
		if( i < 53 ) cout << ' ' ; 
	}
	return 0 ; 
}

Is It a Binary Search Tree (25)
题意:给定前序是BST的前序,或者是BST镜像的前序,求后序遍历
思路:BST的左子树小于根节点,右子树大于根节点,镜像正好相反,故每次根据前序的根节点,找左子树,右子树,递归判断是否都满足这个性质。

#include 
using namespace std;
const int AX = 1e3 + 66 ;
int pre[AX] ; 
vector<int>res ;
bool check_min( int l , int r ){
	if( l > r ) return true ;
	int m = l + 1 ;
	int rt = pre[l] ; 
	while( pre[m] < rt && m <= r ) m ++ ; //left_tree
	for( int i = m ; i <= r ; i++ ){
		if( pre[i] < rt ) return false ; 
	}
	if( !check_min( l + 1 , m - 1 ) ) return false ;
	if( !check_min( m , r ) ) return false ;
	res.push_back(rt);
	return true; 
}

bool check_max( int l , int r ){
	if( l > r ) return true ;
	int m = l + 1 ;
	int rt = pre[l] ; 
	while( pre[m] >= rt && m <= r ) m ++ ; //left_tree
	for( int i = m ; i <= r ; i++ ){
		if( pre[i] > rt ) return false ; 
	}
	if( !check_max( l + 1 , m - 1 ) ) return false ;
	if( !check_max( m , r ) ) return false ;
	res.push_back(rt);
	return true; 
}

void print() {
	printf("YES\n");
	int len = res.size() ;
	for( int i = 0 ; i < len ; i++ ) {
		printf("%d",res[i]);
		if( i != len - 1 ) printf(" ");
	}
}

int main(){
	int n ;
	scanf("%d",&n);
	for( int i = 0 ; i < n ; i++ ){
		scanf("%d",&pre[i]);
	}
	if( check_min( 0 , n - 1 ) ){
		print();
		return 0 ;
	}
	res.clear();
	if( check_max( 0 , n - 1 ) ){
		print();
		return 0 ; 
	}
	printf("NO");
	return 0 ; 
}

Shopping in Mars (25)
题意:寻找连续子序列,使其和大于等于m,且与m差值最小的所有起止位置
思路:滑动窗口

#include 
#define INF 0x3f3f3f3f
using namespace std;
typedef pair<int,int>P;
const int AX = 1e5 + 66 ;
int a[AX] ; 
vector<P>res;
int main(){
	int n , m ; 
	scanf("%d%d",&n,&m);
	for( int i = 1 ; i <= n ; i++ ){
		scanf("%d",&a[i]);
	}
	int st = 1 , ed = 1 ;
	int dv = INF ; 
	int sum = 0 ; 
	while( st <= ed ){
		while( ed <= n && sum < m ) sum += a[ed++] ;  
		if( sum < m ) break ; 
		if( dv > sum - m ){
			dv = sum - m ; 
			res.clear() ; 
			res.push_back(P(st,ed-1));
		}else if( dv == sum - m ){
			res.push_back(P(st,ed-1));
		}
		sum -= a[st++] ; 
	}
	for( auto x : res ){
		printf("%d-%d\n",x.first,x.second);
	}
	return 0 ; 
}

Shortest Distance (20)
题意:给一个环的相邻点距离,对于给定的查询,输出最小距离。
思路:前缀和,不过因为是环,要将原数组扩充一遍

#include 
using namespace std;
const int AX = 2e5 + 666 ;
int a[AX] ; 
int sum[AX] ; 
int main(){
	int n ;
	scanf("%d",&n);
	for( int i = 1 ; i <= n ; i ++ ){
		scanf("%d",&a[i]);
	}
	for( int i = n + 1 ; i <= 2 * n ; i++ ){
		a[i] = a[i-n] ; 
	}
	sum[0] = 0 ; 
	for( int i = 1 ; i <= 2 * n ; i++ ){
		sum[i] = sum[i-1] + a[i] ;
	}
	int m ;
	scanf("%d",&m);
	int x , y ;  
	while( m-- ){
		scanf("%d%d",&x,&y);
		if( x > y ) swap(x,y);
		printf("%d\n",min( sum[y-1]-sum[x-1] , sum[n+x-1] - sum[y-1] ) );
	}
	return 0 ; 
}

Student List for Course (25)

#include 
using namespace std;
const int AX = 3e3 + 66 ;
vector<string>c[AX];
bool cmp( string a , string b ){
	return a < b ; 
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	int n , k , num , x ;
	string stu ;
	cin >> n >> k ;
	for( int i = 0 ; i < n ; i++ ) {
		cin >> stu >> num ;
		for( int j = 0 ; j < num ; j++ ) {
			cin >> x ;
			c[x].push_back(stu);
		}
	}
	for( int i = 1 ; i <= k ; i++ ) {
		int len = c[i].size() ;
		sort( c[i].begin() , c[i].end() );
		cout << i << ' ' << len << endl;
		for( int j = 0 ; j < len ; j++ ) {
			cout << c[i][j] ;
			if( !( i == k && j == len - 1 ) ) cout << endl;
		}
	}
	return 0 ;
}

Find Coins (25)
题意:找两个数的和等于k

#include 
using namespace std;
const int AX = 1e5 + 666 ;
int a[AX];
map<int,int>mp;
int main() {
	int n , k ,x ; 
	scanf("%d%d",&n,&k);
	for( int i = 0 ; i < n ; i++ ){
		scanf("%d",&a[i]);
		mp[a[i]] = 1 ; 
	}
	sort( a , a + n );
	int l = -1 , r ; 
	for( int i = 0 ; i < n ; i++ ){
		if( a[i] > k ) break ; 
		if( mp[ k - a[i] ] ){
			l = a[i] ; 
			r = k - a[i] ;
			if( l > r ) swap( l , r ) ;
			break ; 
		}
	}
	if( l == -1 ) printf("No Solution");
	else printf("%d %d",l,r);
	return 0 ;
}

Counting Ones (30)
题意:统计数字1-N中1出现次数

/*统计1-n中0-9出现次数*/
#include 
#define LL long long
using namespace std;
const int AX = 20;
LL c[AX];
void dfs( LL a , LL base ) {
	LL n = a / 10 ;
	int m = a % 10;
	for( int i = 0 ; i <= m ; i++ ) c[i] += base ;           //I当前位对低位的影响
	for( int i = 0 ; i < 10 ; i++ ) c[i] += base * n ;    //Ⅱ高位对低位的影响
	c[0] -= base ;        //减去多算的0
	LL temp = n ;
	while( temp ) {                 //Ⅲ当前位对高位的影响(例如456 得考虑450,451,452...456,所以c[4]+=7,c[5]+=7 )
		c[temp%10] += base * ( m + 1 ) ;
		temp /= 10 ;
	}
	if( n ) dfs( n - 1 , base * 10 ) ;   //n处理过,从n-1开始
}
int main() {
	LL a ;
	cin >> a ;
	dfs( a , 1 ) ;
	cout << c[1] ;
	return 0;
}
/*
如:4567,以第一轮为例
每次递归将最后一位统计完全
<
	 Ⅰ  处统计4560-4567中的末尾数字0-7次数
	 Ⅱ  处统计(0000-4559)中末尾数字0-9出现次数
>
并且把每次递归的几个高位数字统计上
	 Ⅲ  处统计(4560-4567)中的高位(456处)数字出现次数(至此456x的所有数字都统计完了,下次递归从455开始)
*/

String Subtraction (20)

#include 
using namespace std;
map<char,int>mp;
int main(){
	string s , b ;
	getline( cin , s ) ;
	getline( cin , b ) ;
	for( int i = 0 ; i < b.size() ; i++ ){
		mp[b[i]] = 1 ; 
	}
	for( int i = 0 ; i < s.size() ; i++ ){
		if( !mp[s[i]] ){
			cout << s[i] ;
		}
	}
	return 0 ;
}

Pop Sequence (25)
题意:入栈次序为1-n,栈容量最大m,问给定的每个出栈序列是否成立

#include 
using namespace std;
int n , m , q ; // 1 - n push , size == m
bool check( vector<int> v ) {
	stack<int> s;
	int id = 0 ;
	for( int i = 1 ; i <= n ; i++ ) {
		s.push(i) ;
		if( s.size() > m ) return false ;
		if( s.size() && s.top() == v[id] ) {
			while( s.size() && s.top() == v[id] ) {
				s.pop();
				id ++ ;
			}
		} 
	}
	return !s.size();
}
int main() {
	scanf("%d%d%d",&m,&n,&q);
	int x ;
	vector<int>v;
	while( q-- ) {
		v.clear();
		for( int i = 0 ; i < n ; i++ ) {
			scanf("%d",&x);
			v.push_back(x);
		}
		if( check(v) ) printf("YES\n");
		else printf("NO\n");
	}
	return 0 ;
}

Linked List Sorting (25).

#include 
using namespace std;
const int AX = 1e5 + 666 ; 
struct Node{
	int val , adr , nxt ; 
	bool operator < ( const Node &a )const{
		return val < a.val ; 
	}
}a[AX] ; 
vector<Node>v;
map<int,int>mp;
int main(){
	int n , x ; 
	scanf("%d%d",&n,&x);
	for( int i = 0 ; i < n ; i++ ){
		scanf("%d%d%d",&a[i].adr,&a[i].val,&a[i].nxt);
		mp[a[i].adr] = i;
	}
	int tmp = x ;   
	while( tmp != -1 ){
		int idx = mp[tmp] ; 
		v.push_back(a[idx]);
		tmp = a[idx].nxt ; 
	}
	sort( v.begin() , v.end() );
	int len = v.size() ; 
	if( !len ){
		return 0*printf("0 -1");
	}
	printf("%d %05d\n",len,v[0].adr);
	for( int i = 0 ; i < len ; i++ ){
		int nxt = ( i + 1 == len ? -1 : v[i+1].adr ) ;
		printf("%05d %d ",v[i].adr,v[i].val);
		if( nxt == -1 ) printf("%d",nxt);
		else printf("%05d",nxt);
		if( i != n - 1 ) printf("\n");
	}
	return 0 ; 
}

Path of Equal Weight (30)

#include 
using namespace std;
typedef pair<int,int>P;
const int AX = 1e2 + 6 ;
int v[AX] ;
struct Node {
	int to , w ;
	Node( int to , int w ):to(to),w(w) {}
	bool operator < ( const Node &x )const {
		return w > x.w ;
	}
};
vector<Node>G[AX];
int tot = 0 ;
vector<int>res[AX];
vector<int>tmp;
int n , m , k ;
void dfs( int x , int sum ) {
	if( !G[x].size() && sum == k ) {
		res[tot++] = tmp ;
		return ;
	}
	for( int i = 0 ; i < G[x].size() ; i++ ) {
		int w = G[x][i].w ;
		int y = G[x][i].to  ;
		tmp.push_back(w) ;
		dfs( y , sum + w ) ;
		tmp.pop_back();
	}
}
int main() {
	scanf("%d%d%d",&n,&m,&k);
	for( int i = 0 ; i < n ; i++ ) {
		scanf("%d",&v[i]);
	}
	int x , q , y ;
	for( int i = 0 ; i < m ; i++ ) {
		scanf("%d%d",&x,&q);
		for( int j = 0 ; j < q ; j++ ) {
			scanf("%d",&y);
			G[x].push_back(Node(y,v[y]));
		}
	}
	for( int i = 0 ; i < n ; i++ ) {
		sort( G[i].begin() , G[i].end() );
	}
	dfs(0,v[0]);
	for( int i = 0 ; i < tot ; i ++ ){
		int len = res[i].size() ; 
		printf("%d ",v[0]);
		for( int j = 0 ; j < len ; j++ ){
			printf("%d",res[i][j]);
			if( j != len - 1 ) printf(" ");
		}
		if( i != tot - 1 ) printf("\n");
	}
	return 0 ;
}

The Dominant Color (20)
题意:找矩阵中出现次数最多的

#include 
#define LL long long 
using namespace std;
const int AX = 8e2 + 66 ; 
LL a[AX][AX];
map<LL,int>mp;
int main(){
	int m , n ; 
	scanf("%d%d",&m,&n);
	for( int i = 0 ; i < n ; i++ ){
		for( int j = 0 ; j < m ; j++ ){
			scanf("%lld",&a[i][j]);
			mp[a[i][j]] ++ ; 
		}
	}
	int ans = 0 ; LL res ; 
	for( auto x : mp ){
		if( ans < x.second ){
			ans = x.second ; 
			res = x.first ; 
		}
	}
	printf("%lld",res);
	return 0 ;
}

Hello World for U (20)

#include 
using namespace std;
const int AX = 1e2 + 66 ;
string res[AX];
int main(){
	string s ; 
	cin >> s ; 
	int N = s.size() ; 
	int n1 = 100 , n2 = 0 , n3 ; 
	int t1 , t2 , t3 ;
	for( int i = 3 ; i <= N ; i++ ){
		if( !( ( N - i + 2 ) & 1 ) ){
			t1 = ( N - i + 2 ) / 2 ;
			t3 = t1 ;
			t2 = i ;
			if( t1 <= t2 && abs(n1 - n2) > abs(t1 - t2) ){
				n1 = t1 ;
				n2 = t2 ;
				n3 = t3 ;
			} 
		}
	}
	for( int i = 0 ; i < n1 ; i++ ){
		for( int j = 0 ; j < n2 ; j++ ){
			res[i][j] = ' ' ; 
		}
	}
	//cout << n1 << ' ' << n2 << endl;
	int tot = 0 ;
	int r = 0 , c = 0 ;
	for( ; r < n1 ; r ++ ){
		res[r][c] = s[tot++] ;
	}
	c ++ ;
	r -- ; 
	for( ; c < n2 ; c ++ ){
		res[r][c] = s[tot++] ;
	}
	r -- ;
	c -- ;
	for( ; r >= 0 ; r -- ){
		res[r][c] = s[tot++] ;
	}
	for( int i = 0 ; i < n1 ; i++ ){
		for( int j = 0 ; j < n2 ; j++ ){
			cout << res[i][j] ;
		}
		if( i != n1 - 1 ) cout << endl ;
	}
	return 0 ;
}

Sharing (25)

#include 
using namespace std;
const int AX = 1e5 + 666 ;
struct Node{
	char v ; 
	int nxt ;
	Node(){}
	Node( char v , int nxt ):v(v),nxt(nxt){}
}a[AX];
map<int,int>mp;
bool check( int st ){
	int st1 = st , st2 = st ;
	while( st2 != -1 ){
		if( a[st1].v != a[st2].v ) return false ;
		st2 = a[st2].nxt ;
		st1 = a[st1].nxt ; 
	}
	return ( st1 == -1 && st2 == -1 );
}
int main(){
	int h1 , h2 , n ; 
	scanf("%d%d%d",&h1,&h2,&n);
	char w[5] ;
	int address , next1 ;
	for( int i = 0 ; i < n ; i++ ){
		scanf("%d%s%d",&address,w,&next1);
		a[address] = Node( w[0] , next1 );
	}
	int res = -1 ;
	while( h1 != -1 ){
		mp[h1] ++ ;
		h1 = a[h1].nxt ; 
	}
	while( h2 != -1 ){
		if( mp[h2] && check(h2) ){
			res = h2 ; 
			break ; 
		}
		h2 = a[h2].nxt ; 
	}
	if( res == -1 ) printf("-1");
	else printf("%05d",res);
	return 0 ; 
}

To Fill or Not to Fill (25)

//贪心:先按照加油站距离升序排序,然后采取如下贪心策略:
    /*从当前所在加油站向后找(装满油能达到的范围内找),
         *如果有花费更少的的加油站x1,则加油加到能到达x1为止;
         *如果范围内的加油站花费都大,则加满油。
         *途中更新剩余油量,以及到达距离。
         *注意精度问题,剩余油量小于0不一定是无法到达,
         *因为精度的原因,在一定范围内,可以允许油量小于0(我设置的允许范围是10^(-10)).
    */
#include 
#define inf 1e-10  // 允许的误差范围
using namespace std;
const int AX = 5e2 + 66 ;
struct Node {
    double p , d ;
    bool operator < ( const Node & x )const {
        return d < x.d ;
    }
} a[AX];
int main() {
    double V , d , x; int n ;
    scanf("%lf%lf%lf%d",&V,&d,&x,&n);
    for( int i = 0 ; i < n ; i++ ) {
        scanf("%lf%lf",&a[i].p,&a[i].d);
    }
    a[n++].d = d ;
    double res = 0.0 , dis = 0.0 , left = 0.0 ;
    sort( a , a + n );
    int f = 0 ;
    for( int i = 0 ; i < n ; i++ ) { 
        if( i ) f = 1 ; //走过距离是否为0
        int id = i ;
        left -= ( a[i].d - ( ( !i ) ? 0.0 : a[i-1].d ) ) / x ;
        if( a[i].d == d ) { dis = d ; break ; }
        if( left < 0 ) {
            if( 0-left > inf ) { 
                dis = ( ( !i ) ? 0.0 : a[i-1].d ) ; //超过允许的范围,则不可达
                break ;
            } else left = 0 ; //油量用光
        } else dis = a[i].d;
        for( int j = i + 1 ; j < n ; j++ ) {
            if( a[j].d > d ) break ;
            if( V * x >= a[j].d - a[i].d ) {  //可达范围内寻找花费比自己少的加油站
                if( a[j].p < a[i].p ) {
                    id = j ;
                    break ;
                }
            } else break ;
            id = j ;
        }
        if( a[id].p < a[i].p ) { //花费少更新油量为能达到此加油站
            double ned = ( a[id].d - a[i].d ) / x ;
            if( ned > left ) {
                res += ( ned - left ) * a[i].p ;
                left = ned ;
            }
        } else {  //范围内没有花费更少的则加满油
            res += ( V - left ) * a[i].p ;
            left = V ;
        }
    }
    if( dis < d ) {
        if( f ) printf("The maximum travel distance = %.2lf",dis+V*x);
        else printf("The maximum travel distance = 0.00");
    } else {
        printf("%.2lf",res);
    }
    return 0 ;
}

Head of a Gang (30)

#include 
using namespace std;
const int AX = 1e3 + 66 ;
map<string,int>mp ;
map<int,string>mp1 ;
int vis[AX] ;
int v[AX] ;
int v_from[AX] ;
int id , num , ans , idx ;
int n , k ;
vector<int>G[AX] ;
struct Node{
	string name ;
	int num ; 
	Node( string name , int num ):name(name),num(num){}
	bool operator < ( const Node &x )const {
		return name < x.name ; 
	}
};
vector<Node>res ;
void dfs( int x ){
	for( int i = 0 ; i < G[x].size() ; i++ ){
		int to = G[x][i] ; 
		if( !vis[to] ){ 
			vis[to] = 1 ; 
			num ++ ; 
			ans += v_from[to]; 
			if( v[to] > v[idx] ) idx = to ;
			dfs( to );
		}
	}
}
int main() {
	id = 0 ;
	char x[5] , y[5] ;
	int t ; 
	scanf("%d%d",&n,&k);
	memset( v , 0 , sizeof(v) ) ;
	memset( vis , 0 , sizeof(vis) ) ;
	for( int i = 0 ; i < n ; i++ ) {
		scanf("%s%s%d",x,y,&t);
		if( !mp[(string)x] ){ mp[(string)x] = ++id ; mp1[id] = x ; }
		if( !mp[(string)y] ){ mp[(string)y] = ++id ; mp1[id] = y ; }
		int xx = mp[(string)x] ; 
		int yy = mp[(string)y] ; 
		v[xx] += t ; v[yy] += t ;
		v_from[xx] += t ; 
		G[xx].push_back(yy);
		G[yy].push_back(xx);
	}
	for( int i = 1 ; i <= id ; i++ ){
		if( !vis[i] ){
			num = 1 ;
			ans = v_from[i] ; 
			vis[i] = 1 ;
			idx = i ;
			dfs(i);
			if( ans > k && num > 2 ){
				res.push_back(Node(mp1[idx],num));
			}
		}
	}
	sort( res.begin() , res.end() );
	int len =  res.size() ; 
	printf("%d\n",len);
	for( int i = 0 ; i < len ; i++ ){
		printf("%s %d",res[i].name.c_str(),res[i].num);
		if( i != len - 1 ) printf("\n");
	}
	return 0 ;
}

Recover the Smallest Number (30)
题意:求n个数字组合成的n!的组合中转化成数字最小的组合方式
思路:如果ab组合小于ba组合,那么肯定这样排列结果才对,故每一对都满足,并且满足传递性。按照这个方案排序即可。

#include 
using namespace std;
bool cmp( string a , string b ){  //传递性 
	return a + b < b + a ; 
}
vector<string>v;
int main(){
	int n ; 
	string s ;
	cin >> n ;
	for( int i = 0 ; i < n ; i++ ){
		cin >> s ;
		v.push_back(s);
	}
	sort( v.begin() , v.end() , cmp );
	string ans = "" , res = "" ;
	for( int i = 0 ; i < v.size() ; i++ ){
		ans += v[i] ; 
	}
	int f = 0 ; 
	for( int i = 0 ; i < ans.size() ; i++ ){
		if( !f && ans[i] == '0' ) continue ;
		f = 1 ; res += ans[i] ;
	}
	if( !res.size() ) cout << "0" ;
	else cout << res ;
	return 0 ; 
}

Course List for Student (25)

#include 
using namespace std;
const int AX = 4e4 + 666 ;
map<string,int>mp;
vector<int>res[AX];
int main(){
	int q , m ; 
	scanf("%d%d",&q,&m);
	int cid , k ; 
	char stu[10] ;
	int id = 0 ;
	for( int i = 0 ; i < m ; i++ ){
		scanf("%d%d",&cid,&k);
		for( int j = 0 ; j < k ; j++ ){
			scanf("%s",stu);
			if( !mp[(string)stu] ){
				mp[(string)stu] = ++id ;
			}
			res[mp[(string)stu]].push_back(cid);
		}
	}
	for( int j = 0 ; j < q ; j++ ){
		scanf("%s",stu);
		printf("%s ",stu);
		int sid = mp[stu] ;
		int len = res[sid].size() ; 
		printf("%d",len);
		if( len ) printf(" ");
		sort( res[sid].begin() , res[sid].end() );
		for( int i = 0 ; i < len ; i++ ){
			printf("%d",res[sid][i]);
			if( i != len - 1 ) printf(" ");
		}
		if( j != q - 1 ) printf("\n");
	}
	return 0 ; 
}

Longest Symmetric String (25)
最长回文子串,Manacher算法

#include 
using namespace std;
const int AX = 2e3 + 66 ;
char s[AX] ;
int p[AX] ;
int main(){
	fgets( s , AX , stdin );
	int len = strlen(s);
	for( int i = len ; i >= 0 ; i-- ){
		s[2*i+2] = s[i];
		s[2*i+1] = '#';
	}
	s[0] = '$' ; 
	int res = -1 ; 
	int id = 0 , mx = 0 ;
	for( int i = 2 ; i < 2 * len + 1 ; i++ ){
		if( p[id] + id > i ) p[i] = min( p[id] + id - i , p[2*id-i] );
		else p[i] = 1 ; 
		while( s[i-p[i]] == s[i+p[i]] ) p[i] ++ ; 
		if( mx < i + p[i] ){
			mx = i + p[i] ; 
			id = i ;
		}
		res = max( res , p[i] ) ;
	}
	printf("%d",res-1);
	return 0 ; 
}

Dating (20)

//3485djDkxh4hhGE
//2984akDfkkkkggEdsb
//first common capital character -> day
//the second common character -> 14hours ( 0 - 9 , A - N )
//s&hgsfdk
//d&Hyscvnm

//shared by the last two strings is 's' at the 4th (0开始) -> minute
#include 
using namespace std;
const int AX = 2e3 + 66 ;
string mp[10] = { "MON" , "TUE" , "WED" , "THU" , "FRI" , "SAT" , "SUN" } ;
int main(){
	string s[5] ; 
	for( int i = 0 ; i < 4 ; i++ ){
		cin >> s[i] ;
	}
	int day , h , m ; 
	int f = 0 ; 
	int len = min( s[0].size() , s[1].size() );
	for( int i = 0 ; i < len ; i++ ){
		if( !f && s[0][i] >= 'A' && s[0][i] <= 'Z' && s[1][i] >= 'A' && s[1][i] <= 'Z' && s[0][i] == s[1][i] ){
			day =  (int)( s[0][i] - 'A' ) ;
			f = 1 ; 
			continue ; 
		}
		if( f == 1 && s[0][i] >= 'A' && s[0][i] <= 'N' && s[1][i] >= 'A' && s[1][i] <= 'N' && s[0][i] == s[1][i] ){
			h = 10 + s[0][i] - 'A' ; 
			break ; 
		}
		if( f == 1 && s[0][i] >= '0' && s[0][i] <= '9' && s[1][i] >= '0' && s[1][i] <= '9' && s[0][i] == s[1][i] ){
			h = s[0][i] - '0' ; 
			break ; 
		}
	}
	len = min( s[2].size() , s[3].size() );
	for( int i = 0 ; i < len ; i++ ){
		if( s[2][i] >= 'A' && s[2][i] <= 'Z' && s[3][i] >= 'A' && s[3][i] <= 'Z' && s[2][i] == s[3][i] ){
			m = i ; 
			break ; 
		}else if( s[2][i] >= 'a' && s[2][i] <= 'z' && s[3][i] >= 'a' && s[3][i] <= 'z' && s[2][i] == s[3][i] ){
			m = i ; 
			break ; 
		}
	}
	cout << mp[day] << ' ' ;
	std::cout << std::setw(2) << std::setfill('0') << h << ":" ;  
	std::cout << std::setw(2) << std::setfill('0') << m ;  
	return 0 ; 
}

Talent and Virtue (25)

#include 
using namespace std;
struct Node{
	string s ; 
	int v ;
	int t ;
	Node( string s , int v , int t ):s(s),v(v),t(t){}
	bool operator < ( const Node &x )const{
		if( v + t == x.v + x.t ) {
			if( v == x.v ) return s < x.s;
			return v > x.v; 
		}else return v + t > x.v + x.t ; 
	}
};
vector<Node>vec[10] ; 
int main(){
	int n , L , H , vg , tg ; 
	char name[20] ; 
	scanf("%d%d%d",&n,&L,&H);
	for( int i = 0 ; i < n ; i++ ){
		scanf("%s%d%d",name,&vg,&tg);
		if( vg < L || tg < L ) continue ; 
		if( vg >= H && tg >= H ){ //sages
			vec[0].push_back(Node((string)name,vg,tg));
		}else if( tg < H && vg >= H ){//nobleman
			vec[1].push_back(Node((string)name,vg,tg));
		}else if( tg < H && vg < H && vg >= tg ){
			vec[2].push_back(Node((string)name,vg,tg));
		}else{
			vec[3].push_back(Node((string)name,vg,tg));
		}
	}
	int res = 0 ;
	for( int i = 0 ; i < 4 ; i++ ){
		res += vec[i].size() ; 
		if( vec[i].size() ){
			sort( vec[i].begin() , vec[i].end() );
		}
	}
	printf("%d\n",res);
	for( int i = 0 ; i < 4 ; i++ ){
		int len = vec[i].size() ; 
		if( len ){
			for( int j = 0 ; j < len ; j++ ){
				printf("%s %d %d",vec[i][j].s.c_str(),vec[i][j].v,vec[i][j].t);
				if( !( i == 3 && j == len - 1 ) ) printf("\n");
			}
		}
	}
	return 0 ;
}

The Black Hole of Numbers (20)

#include 
using namespace std;
bool cmp( char a , char b ) {
	return a > b ;
}
char s[10] , b[10] ;
void change() {
	int len1 = strlen(s) ;
	int tmp = len1 ; 
	for( int i = 3 ; len1 && i >= 0 ; i-- ) {
		s[i] = s[len1-1];
		len1-- ; 
	}
	for( int i = 0 ; i < 4 - tmp ; i++ ){
		s[i] = '0' ; 
	}
	s[4] = '\0' ; 
}
int main() {

	scanf("%s",s) ;
	change();
	strcpy(b,s);
	sort( b , b + 4 ) ;
	sort( s , s + 4 , cmp ) ;
	int x, y, z ;
	while(1) {
		x = atoi(s);
		y = atoi(b);
		if( x == y ) {
			printf("%04d - %04d = 0000",x,y);
			break ;
		}
		z = x - y ;
		printf("%04d - %04d = %04d",x,y,z);
		if( z == 6174 ) break ;
		printf("\n");
		stringstream ss ;
		ss << z ;
		ss >> s ;
		change();
		strcpy( b , s );
		sort( b , b + 4 ) ;
		sort( s , s + 4 , cmp ) ;
	}
	return 0 ;
}


Mooncake (25)

#include 
using namespace std;
const int AX = 1e3 + 66 ;
struct Node{
	double inv , p ; 
	bool operator < ( const Node &a )const{
		return ( ( p / inv ) - ( a.p / a.inv ) ) > 0 ;
	}
}a[AX];
vector<Node>v;
int main(){
	int n ;
	double d , x ;	
	scanf("%d%lf",&n,&d);
	for( int i = 0 ; i < n ; i++ ){
		scanf("%lf",&a[i].inv);
	}
	for( int i = 0 ; i < n ; i++ ){
		scanf("%lf",&a[i].p);
		if( a[i].inv ) v.push_back(a[i]);
	}
	sort( v.begin() , v.end() );
	double res = 0.0 ; 
	for( int i = 0 ; i < (int)v.size() ; i++ ){
		if( d <= 0 ) break ;
		double tmp = ( ( d >= v[i].inv ) ? v[i].inv : d ) ;
		res += ( tmp / v[i].inv * v[i].p ) ;
		d -= tmp ; 
	}
	for( int i = 0 ; i < n ; i++ ){
		if( !a[i].inv ){
			res += a[i].p ; 
		}
	}
	printf("%.2lf",res);
	return 0 ;
}

Scientific Notation (20)

#include 
using namespace std;
const int AX = 1e5 + 666 ;
char s[AX];
int main() {
	scanf("%s",s);
	if( s[0] == '-' ) printf("-");
	char *p = strtok( s , "E" ) ; //'E'处置为'/0'
	int len = strlen(s) ;
	p = s + len + 1 ;
	if( *p == '+' ) {
		p ++ ;
		int exp = atoi(p);
		int idx = 2 + exp ;
	
		for( int i = 1 ; i < len ; i++ ) {
			if( s[i] != '.' ) printf("%c",s[i]);
			if( i == idx && s[i+1] != 'E' ) printf(".");
		}
		//cout << len << endl;
		int left = max( 0 , exp - ( len - 3 ) ) ;
		for( int i = 0 ; i < left ; i++ ){
			printf("0");
		}
	} else {
		p ++ ;
		int exp = atoi(p);
		if( exp ) printf("0.");
		for( int i = 0 ; i < max( 0 , exp - 1 ) ; i++ ){
			printf("0");
		}
		for( int i = 1 ; i < len ; i++ ){
			if( s[i] != '.' ) printf("%c",s[i]);
		}
	}
	return 0 ;
}

Reversing Linked List (25)
题意:给定的链表,每K个数逆置,不够K个数的不动
思路:可以不用真的逆置指针,直接每k个数逆序,存起来就行

#include 
using namespace std ;
const int AX = 1e5 + 66 ;
struct Node {
	int adr , v , nxt ;
	Node(){}
	Node( int adr , int v , int nxt ):adr(adr),nxt(nxt),v(v) {}
} a[AX] ;
vector<Node>res ;
vector<Node>vec ; 
int main() {
	int st , val , adr , nxt ; 
	int n , k ;
	scanf("%d%d%d",&st,&n,&k);
	for( int i = 0 ; i < n ; i++ ) {
		scanf("%d%d%d",&adr,&val,&nxt);
		a[adr] = Node(adr,val,nxt);
	}
	int t = st ;
	while( t != -1 ) {
		int tmp = k ;
		vec.clear() ;
		while( tmp-- && t != -1 ) {
			vec.push_back(a[t]);
			t = a[t].nxt ; 
		}
		if( vec.size() == k ) reverse( vec.begin() , vec.end() ); 
		for( int i = 0 ; i < vec.size() ; i++ ){
			res.push_back(vec[i]);
		}
	}
	int len = res.size() ;
	for( int i = 0 ; i < len ; i++ ){
		printf("%05d %d ",res[i].adr,res[i].v);
		if( i == len - 1 ) printf("-1");
		else printf("%05d\n",res[i+1].adr);
	}
	return 0 ;
}

Broken Keyboard (20)

#include 
using namespace std;
map<char,int>mp1;
map<char,int>mp;
int main(){
	char s[100];
	char t[100];
	cin >> s >> t ; 
	for( int i = 0 ; i < strlen(t) ; i++ ){
		char ch = t[i];
		if( ch >= 'a' && ch <= 'z' ) ch = toupper(ch);
		mp1[ch] = 1 ;
	}
	vector<char>res;
	for( int i = 0 ; i < strlen(s) ; i++ ){
		char ch = s[i];
		if( ch >= 'a' && ch <= 'z' ) ch = toupper(ch);
		if( !mp1[ch] && !mp[ch] ) {
			mp[ch] = 1 ;
			res.push_back(ch);
		}
	}
	for( int i = 0 ; i < res.size() ; i++ ){
		cout << res[i] ;
	}
	return 0 ;
}

Perfect Sequence (25)
思路:枚举左端二分右端

#include 
#define LL long long
using namespace std;
const int AX = 1e5 + 666 ;
int n ;
LL p ;
LL a[AX] ;
bool check( int st , int ed ) {
	return a[ed] <= p * a[st] ;
}
int binary_search( int st ) {
	int l = st , r = n - 1 ;
	while( l <= r ) {
		int mid = ( l + r ) >> 1 ;
		if( check( st , mid ) ) l = mid + 1 ;
		else r = mid - 1 ;
	}
	return l ;
}
int main() {
	scanf("%d%lld",&n,&p);
	for( int i = 0 ; i < n ; i++ ) {
		scanf("%lld",&a[i]);
	}
	sort( a , a + n ) ;
	int res = 0 ;
	for( int i = 0 ; i < n ; i++ ) {
		int pos = binary_search(i) ;
		if( pos >= i && pos < n && check( i , pos ) ) {
			res = max( res , pos - i + 1 );
		} else if( pos - 1 >= i && pos - 1 < n && check( i , pos - 1 ) ) {
			res = max( res , pos - 1 - i + 1 );
		}
	}
	printf("%d",res);
	return 0 ;
}

Insert or Merge (25)

/*先判断是否是归并排序
*枚举间隔,看间隔内的数是否是有序且和原序列的数相同;
*只有此间隔下所有集合有序且与原数组元素相符才能判断是归并;
*若是归并,则扩大间隔,每个间隔内排序即得下步;
*若是插入,则直接寻址不符合有序的一个元素向前插入到适合位置即可。
*/

#include 
using namespace std;
const int AX = 1e2 + 66 ;
int n ;
map<int,int>mp;
int a[AX];
int b[AX];
int ans ; 
bool check_sort( int l , int r ){
	int ans = 0 ;
	mp.clear() ; 
	for( int i = l ; i <= r ; i++ ){
		mp[a[i]] ++ ;
	}
	for( int i = l ; i < r ; i++ ){
		mp[b[i]] -- ; 
		if( b[i+1] < b[i] ) return false ;
	}mp[b[r]] -- ;
	for( auto i : mp ){
		if( i.second ) return false ; 
	}
	return true ; 
}
int check_merge(){
	for( int d = 2 ; d <= n ; d *= 2 ){
		int f = 1 ; 
		for( int i = 0 ; i < n ; i += d ){
			if( !check_sort( i , min( n - 1 , i + d - 1 ) ) ){
				f = 0 ; break ;  
			}
		}
		if( f ) { ans = d ; return true ; }
	}
	return false ; 
}
int main() {
	scanf("%d",&n);
	for( int i = 0 ; i < n ; i++ ) {
		scanf("%d",&a[i]);
	}
	for( int i = 0 ; i < n ; i++ ) {
		scanf("%d",&b[i]);
	}
	if( check_merge()  ) {
		printf("Merge Sort\n");
		ans *= 2 ; 
		for( int i = 0 ; i < n ; i += ans ){
			sort( b + i , b + min( n , i + ans ) );
		}
	}else{
		printf("Insertion Sort\n");
		for( int i = 1 ; i < n ; i++ ){
			if( b[i] < b[i-1] ){
				while(b[i] < b[i-1]){
					swap( b[i] , b[i-1] );
					i -- ; 
				}
				break ;
			}
		}
	}
	for( int i = 0 ; i < n ; i++ ){
		printf("%d",b[i]);
		if( i != n - 1 ) printf(" ");
	}
	return 0 ;
}

To Buy or Not to Buy (20)

#include 
using namespace std;
map<char,int>mp;
map<char,int>vis;
int main() {
	string s , b ;
	cin >> s >> b ;
	for( int i = 0 ; i < s.size() ; i++ ) {
		mp[s[i]] ++ ;
	}
	int f = 1 ;
	for( int i = 0 ; i < b.size() ; i++ ) {
		if( mp[b[i]] <= 0 ) f = 0 ; 
		mp[b[i]] -- ; 
	}
	int res = 0 ;
	if( f ) {
		cout << "Yes " ; 
		res = s.size() - b.size() ; 
	}else{
		cout << "No " ;
		for( int i = 0 ; i < b.size() ; i++ ){
			if( !vis[b[i]] && mp[b[i]] < 0 ){
				res += 0 - mp[b[i]] ; 
				vis[b[i]] = 1 ; 
			}
		}
	}
	cout << res ; 
	return 0 ;
}

Count PAT’s (25)
思路:容易想到统计一个前缀和,一个后缀和,枚举A的位置,前缀和*右缀和统计得到答案
另一个更具有普适性的解见解法二(未注释部分代码)

/*#include 
#define LL long long 
using namespace std;
const int AX = 1e5 + 666 ; 
const LL MOD = 1e9 + 7 ; 
LL p[AX]; 
LL t[AX]; 
int main(){
	string s ;
	cin >> s ; 
	long long res = 0 ; 
	int len = s.size() ; 
	for( int i = 0 ; i < len ; i++ ){
		if( !i ) p[i] = ( s[i] == 'P' ) ;
		if( i ) p[i] = p[i-1] + ( s[i] == 'P' ) ;
	}
	t[len] = 0 ; 
	for( int i = len - 1 ; i >= 0 ; i-- ){
		t[i] = t[i+1] + ( s[i] == 'T' ) ;
	}
	for( int i = 1 ; i < len - 1 ; i++ ){
		if( s[i] == 'A' ) res = ( res + 1LL * p[i-1] * t[i+1] ) % MOD ; 
	}
	cout << res ;
	return 0 ;
}*/
#include 
#define LL long long 
using namespace std;
const int AX = 1e5 + 666 ; 
const LL MOD = 1e9 + 7 ; 
int main(){
	string s ;
	cin >> s ; 
	LL p = 0 , pa = 0 , pat = 0 ;
	for( int i = 0 ; i < s.size() ; i++ ){
		if( s[i] == 'P' ) p ++ ;
		if( s[i] == 'A' ) pa = ( pa + p ) % MOD ;
		if( s[i] == 'T' ) pat = ( pat + pa ) % MOD ;
	}
	cout << pat ;
	return 0 ;
}

你可能感兴趣的:(最短路,搜索)