您的位置:首页 > 其它

Codeforces Round #340 (Div. 2) (618A,618B,618C)

2016-01-30 16:45 295 查看

Slime Combining

题目链接:

http://codeforces.com/problemset/problem/618/A
解题思路:

We can simulate the process described in the problem statement. There are many possible implementations of this, so see the example code for one possible implementation. This method can take O(n) time.

However, there is a faster method. It can be shown that the answer is simply the 1-based indices of the one bits in the binary representation of n.
So, we can just do this in O(log n) time.

AC代码(O(n)):

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;

int a[100];

int main(){
int n;
while(~scanf("%d",&n)){
int len = 0;
for(int i = 1; i <= n; i++){
a[len++] = 1;
while(len > 1){
if(a[len-1] == a[len-2]){
a[len-2]++;
len--;
}else
break;
}
}
for(int i = 0; i < len-1; i++)
printf("%d ",a[i]);
printf("%d\n",a[len-1]);
}
return 0;
}

AC代码(O(logn)):

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;

vector<int> v;

int main(){
int n;
while(~scanf("%d",&n)){
v.clear();
int tmp,cnt,flag;
while(n){
tmp = 1;cnt = 1;flag = 0;
while(n >= tmp){
tmp *= 2;
cnt++;
flag = 1;
}
if(flag){
v.push_back(cnt-1);
n -= tmp/2;
}else{
v.push_back(cnt);
n -= tmp;
}
}
printf("%d",v[0]);
for(int i = 1; i < v.size(); i++)
printf(" %d",v[i]);
printf("\n");
}
return 0;
}

Guess the Permutation

题目链接:

http://codeforces.com/problemset/problem/618/B

解题思路:

One solution is to look for the column/row that contains only 1s and 0s. We know that this index must be the index for the element 1. Then, we can repeat this for 2 through n. See the example code for more details. The runtime of this solution is O(n^3).

However, there is an easier solution. One answer is to just take the max of each row, which gives us a permutation. Of course, the element n-1 will appear twice, but we can replace either occurrence with n and be done. See the other code for details

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int vis[55][55];
int p[55];

int main(){
int n;
while(~scanf("%d",&n)){
memset(vis,0,sizeof(vis));
int x;
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
scanf("%d",&x);
vis[i][x]++;
}
sort(vis[i],vis[i]+n);
}
if(n == 2){
printf("2 1\n");
continue;
}
int flag = 1;
for(int i = 0; i < n; i++){
if(flag && vis[i][n-1] == 1)
p[i] = n,flag = 0;
else
p[i] = n-vis[i][n-1];
}
for(int i = 0; i < n-1; i++)
printf("%d ",p[i]);
printf("%d\n",p[n-1]);
}
return 0;
}

Constellation

题目链接:

http://codeforces.com/problemset/problem/618/C

解题思路:

There are many possible solutions to this problem.

The first solution is to choose any nondegenerate triangle. Then, for each other point, if it is inside the triangle, we can replace one of our three triangle points and continue. We only need to make a single pass through the points. We need to be a bit careful
about collinear points in this case.

Another solution is as follows. Let's choose an arbitrary point. Then, sort all other points by angle about this point. Then, we can just choose any two other points that have different angles, breaking ties by distance to the chosen point. (or breaking ties
by two adjacent angles).

AC代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

typedef long long ll;

struct Point{
int id;
int x,y;
Point(int x=0,int y=0):x(x),y(y){}
}po[100005];

typedef Point Vector;

Vector operator - (Vector A,Vector B){
return Vector(A.x-B.x,A.y-B.y);
}

bool judge(Point a,Point b,Point c){
Vector A = a-b;
Vector B = c-b;
return (ll)A.x*B.y-(ll)A.y*B.x;
}

bool cmp(Point a,Point b){
if(a.x != b.x){
return a.x < b.x;
}else{
return a.y < b.y;
}
}

int main(){
int n;
while(~scanf("%d",&n)){
for(int i = 0; i < n; i++){
po[i].id = i+1;
scanf("%d%d",&po[i].x,&po[i].y);
}
sort(po,po+n,cmp);
for(int i = 2; i < n; i++){
if(judge(po[i-2],po[i-1],po[i])){
printf("%d %d %d\n",po[i-2].id,po[i-1].id,po[i].id);
break;
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: