本地: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 ;
}
/*检查大顶堆性质判断是否为堆排序,是就找出末尾位置,调整一次,不是就插入排序来一次*/
#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","a[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 ;
}
#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 ;
}