ecjtu-summer training #4
水题,看谁的时间少谁就赢了,不然就是平局。
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #define ll long long 5 using namespace std; 6 7 int main(){ 8 int n; 9 cin>>n; 10 while(n--){ 11 int h1,h2,m2,m1,s1,s2; 12 cin >> h1>>m1>>s1>>h2>>m2>>s2; 13 int ans1 = h1*3600+m1*60+s1; 14 int ans2 = h2*3600+m2*60+s2; 15 if(ans1 > ans2){ 16 printf("Player2\n"); 17 }else if(ans1 == ans2){ 18 printf("Tie\n"); 19 }else if(ans1 < ans2){ 20 printf("Player1\n"); 21 } 22 } 23 return 0; 24 }
B HDU - 5752
错了好几次,算出来五个if就是错,用下for就对了。
1 #include <iostream> 2 #include <string.h> 3 #include <math.h> 4 #define ll long long 5 using namespace std; 6 int main(){ 7 string s; 8 while(cin>>s){ 9 if(s.length() > 10){ 10 cout << "TAT\n"; 11 continue; 12 } 13 ll ans = 0; 14 for(int i = 0; i < s.length(); i++){ 15 ans = ans*10 + (ll)(s[i]-'0'); 16 } 17 //cout << ans << endl; 18 bool flag = false; 19 for(int i = 1; i <= 5; i ++){ 20 ans = sqrt(ans); 21 if(ans == 1LL){ 22 flag = true; 23 cout << i << endl; 24 break; 25 } 26 } 27 if(!flag)cout << "TAT\n"; 28 } 29 return 0; 30 }
n张图片,和成一个图片,每次合成消耗的值为两个图片社保值之和,优先队列一直取出来两个在放进去一个,直到只有一个图片就OK了。
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 #include <queue> 6 #include <vector> 7 using namespace std; 8 #define ll long long 9 int main(){ 10 ll n,num; 11 priority_queue<ll, vector<ll>, greater<ll> >que; 12 cin>>n; 13 for(int i = 1; i <= n; i ++)cin>>num,que.push(num); 14 if(que.size()==1){ 15 cout << 0 << endl; 16 return 0; 17 } 18 ll sum = 0; 19 while(que.size() != 1){ 20 ll a = que.top(); 21 que.pop(); 22 ll cnt = que.top(); 23 que.pop(); 24 //cout << a << ' ' << cnt << endl; 25 ll ans = a+cnt; 26 sum+=ans; 27 que.push(ans); 28 } 29 cout << sum << endl; 30 return 0; 31 }
大意是有n个袜子,每个的颜色是c1,c2...cn,最多有k中颜色,有m天,每天穿的袜子是左脚穿的颜色是li,右脚穿的颜色是ri,求最少改变几种袜子的颜色可以使的每天穿的袜子的颜色都相同。
并查集就可以做了,所以要穿相同的颜色的袜子为一个集合,在这个集合中要让他们的颜色都变成一样才行,求每个集合里最多的相同的颜色再让集合的大小减去它就是改变最小的数量了。
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 #include <vector> 6 #include <set> 7 #include <map> 8 #define ll long long 9 using namespace std; 10 const int MAX = 2e5+10; 11 int a[MAX],fa[MAX],b[MAX]; 12 map<int,int>mp[MAX]; 13 set<int>st; 14 bool vis[MAX]; 15 int find(int x){ 16 if(fa[x] == x) 17 return x; 18 fa[x] = find(fa[x]); 19 return fa[x]; 20 } 21 int uni(int x,int y){ 22 int xx = find(x); 23 int yy = find(y); 24 if(xx > yy) 25 fa[xx] = yy; 26 else fa[yy] = xx; 27 } 28 int main(){ 29 int n,m,k,l,r; 30 cin>>n>>m>>k; 31 for(int i = 1; i <= n; i ++)scanf("%d",&a[i]); 32 for(int i = 1; i <= n; i ++) 33 fa[i] = i; 34 for(int i = 1; i <= m; i ++){ 35 scanf("%d %d",&l,&r); 36 uni(l,r); 37 vis[l] = true; 38 vis[r] = true; 39 } 40 for(int i = 1; i <= n; i ++){ 41 if(!vis[i])continue; 42 int x = find(i); 43 st.insert(x); 44 b[x]++; 45 mp[x][a[i]]++; 46 } 47 int ans = 0; 48 set<int>::iterator sit; 49 map<int,int>::iterator mit; 50 for(sit = st.begin(); sit != st.end(); ++sit){ 51 int k = (*sit); 52 int MAX = 0; 53 for(mit = mp[k].begin(); mit!=mp[k].end();++mit){ 54 if((*mit).second > MAX) 55 MAX = (*mit).second; 56 } 57 ans += (b[k]-MAX); 58 } 59 cout << ans << endl; 60 return 0; 61 }
题目看了好久,直到最后半个小时才看懂题目,没时间了。
给定n个坐标,求这个坐标左下角的点的数量就是它的rank了,以测试数据为例,比如(3,3)它的左下角只有(1,1),所以它的rank就是1,
输入n个坐标后,让排序,排序规则是y从小到大,y相同是,就让x从小到大,
这样求第i个坐标的rank时,就是求从1到第xi的和了,每次求完一个在更新一下就行,可以用线段树和树状数组来做,线段树写的时候让出错,等以后在更新,贴上数状数组的代码:
1 #include <iostream> 2 #include <stdio.h> 3 #include <algorithm> 4 #include <string.h> 5 using namespace std; 6 const int MAX = 1e5; 7 int tree[MAX+10],a[MAX+10]; 8 9 struct Nod{ 10 int x, y; 11 }nod[MAX]; 12 bool cmp(Nod a, Nod b){ 13 if(a.y == b.y) return a.x < b.x; 14 else return a.y < b.y; 15 } 16 int lowbit(int x){ 17 return x&(-x); 18 } 19 void add(int k, int d){ 20 while(k <= MAX){ 21 tree[k] = tree[k]+d; 22 k = k+ lowbit(k); 23 } 24 } 25 int getSum(int k){ 26 int t = 0; 27 while(k > 0){ 28 t += tree[k]; 29 k -=lowbit(k); 30 } 31 return t; 32 } 33 int main(){ 34 int n; 35 scanf("%d",&n); 36 for(int i = 0; i < n; i ++){ 37 scanf("%d %d",&nod[i].x,&nod[i].y); 38 } 39 sort(nod,nod+n,cmp); 40 for(int i = 0; i < n; i ++){ 41 //printf("%d %d \n",nod[i].x,nod[i].y); 42 a[getSum(nod[i].x)]++; 43 add(nod[i].x,1); 44 } 45 for(int i = 0; i < n; i ++){ 46 printf("%d\n",a[i]); 47 } 48 return 0; 49 }
和ecjtu-summer training #3中的F题一样,只是输出格式变了而已,不多说,直接贴代码:
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 int n, m, ans; 5 char a[50][50]; 6 int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1}; 7 void dfs(int x, int y){ 8 a[x][y] = '#'; 9 for(int i = 0; i < 4; i ++){ 10 int nx = x + dx[i], ny = y + dy[i]; 11 if(0 <= nx && nx < n && 0 <= ny && ny < m && a[nx][ny] == '.'){ 12 ans ++; 13 dfs(nx,ny); 14 } 15 } 16 } 17 int main(){ 18 int k = 1,t; 19 cin >> t; 20 while(~scanf("%d%d",&m,&n)&&m&&n){ 21 ans = 1; 22 for(int i = 0; i < n; i ++) cin >> a[i]; 23 int nx, ny; 24 for(int i = 0; i < n; i ++){ 25 for(int j = 0; j < m; j ++){ 26 if(a[i][j] == '@'){ 27 nx = i; ny = j; 28 goto tt; 29 } 30 } 31 } 32 tt: ; 33 dfs(nx, ny); 34 printf("Case %d: %d\n",k++,ans); 35 //cout << ans << endl; 36 } 37 }
求1到n之间的最短路径,一个dijistra模板题,直接贴代码了:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #define ll long long 5 using namespace std; 6 const int MAX = 1010; 7 const int INF = 0xffffff; 8 int g[MAX][MAX],ans,dist[MAX],n,m; 9 bool vis[MAX]; 10 void dijistra(int x){ 11 int pos = x; 12 for(int i = 1; i <= n; i ++){ 13 dist[i] = g[i][pos]; 14 } 15 vis[pos] = true; 16 for(int i = 1; i <= n; i ++){ 17 int mins = INF; 18 for(int j = 1; j <= n; j ++){ 19 if(!vis[j] && dist[j] < mins){ 20 pos = j; 21 mins = dist[j]; 22 } 23 } 24 vis[pos] = true; 25 for(int j = 1; j <= n; j ++){ 26 if(!vis[j] && dist[j] > dist[pos] + g[pos][j]){ 27 dist[j] = dist[pos] + g[pos][j]; 28 } 29 } 30 } 31 } 32 int main(){ 33 while(scanf("%d %d",&n,&m)!=EOF){ 34 if(n==0&&m==0)break; 35 for(int i = 0; i <= n; i ++) 36 for(int j = 0; j <= n; j ++) 37 g[i][j] = (i==j)?0:INF; 38 for(int i = 0; i < m; i ++){ 39 int a,b,c; 40 scanf("%d %d %d",&a,&b,&c); 41 if(c < g[a][b]){ 42 g[a][b] = c; 43 g[b][a] = c; 44 } 45 } 46 ans = 0; 47 dijistra(1); 48 printf("%d\n",dist[n]); 49 memset(g,0,sizeof(g)); 50 memset(vis,false,sizeof(vis)); 51 memset(dist,0,sizeof(dist)); 52 } 53 return 0; 54 }