# Dhaka2011

## Dhaka2011

### A - Binary Matrix

solution

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const LL inf=1LL<<60;
const int maxn=1010;

int n, m, total;
int row[maxn], col[maxn];

{
scanf("%d%d", &n, &m);
for (int i=1; i<=n; ++i) row[i]=0;
for (int i=1; i<=m; ++i) col[i]=0;
for (int i=1; i<=n; ++i)
for (int j=1; j<=m; ++j)
{
int x;
scanf("%1d", &x);
row[i]+=x; col[j]+=x;
}
}
LL work(int n, int *a)
{
LL ans=inf;
int each=total/n;
for (int i=1; i<=n; ++i)
{
int rest=0;
LL s=0;
int cur=i;
for (int j=1; j<=n; ++j, cur=(cur==n? 1:cur+1))
{
if (a[cur]>each)
{
if (rest<0)
{
int used=min(-rest, a[cur]-each);
s+=used*j; rest+=a[cur]-each;
s-=(a[cur]-each-used)*j;
}
else { s-=(a[cur]-each)*j; rest+=a[cur]-each; }
}
else
{
if (rest>0)
{
int used=min(rest, each-a[cur]);
s+=used*j; rest-=each-a[cur];
s-=(each-a[cur]-used)*j;
}
else { s-=(each-a[cur])*j; rest-=each-a[cur]; }
}
}
ans=min(ans, s);
}
return ans;
}
void solve()
{
total=0;
for (int i=1; i<=n; ++i) total+=row[i];
if (total%n==0 && total%m==0) printf("both ");
else if (total%n==0) printf("row ");
else if (total%m==0) printf("column ");
else { puts("impossible"); return; }

LL ans=0;
if (total%n==0) ans+=work(n, row);
if (total%m==0) ans+=work(m, col);
printf("%lld\n", ans);
}
int main()
{
int casesum;
scanf("%d", &casesum);
for (int i=1; i<=casesum; ++i)
{
printf("Case %d: ", i);
solve();
}
return 0;
}


### B - Candles

solution

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

int n;
int a[20], idx[1<<10];
bool flag[1<<10][210];
LL num[1<<10];

bool cmp(int b, int c)
{
return num[b]<num[c];
}
void init()
{
for (int sett=0; sett<1<<10; ++sett)
{
int cnt=0;
for (int i=0; i<10; ++i)
if (sett>>i & 1) a[++cnt]=i;
num[sett]=0;
for (int i=cnt; i; --i) num[sett]=num[sett]*10+a[i];

for (int i=1; i<=cnt; ++i)
{
flag[sett][a[i]]=true;
for (int j=1; j<=cnt; ++j)
if (i!=j)
{
flag[sett][a[i]*10+a[j]]=true;
flag[sett][a[i]+a[j]]=true;
for (int k=1; k<=cnt; ++k)
if (i!=k && j!=k)
{
flag[sett][a[i]*10+a[j]+a[k]]=true;
for (int p=1; p<=cnt; ++p)
if (i!=p && j!=p && k!=p)
flag[sett][a[i]*10+a[j]+a[k]*10+a[p]]=true;
}
}
}
}
for (int i=0; i<1<<10; ++i) idx[i]=i;
sort(idx, idx+(1<<10), cmp);
}
{
scanf("%d", &n);
for (int i=1; i<=n; ++i) scanf("%d", &a[i]);
return n;
}
void solve()
{
for (int i=0; i<1<<10; ++i)
{
bool can=true;
for (int j=1; j<=n && can; ++j) can&=flag[idx[i]][a[j]];
if (can)
{
printf("%lld\n", num[idx[i]]);
return;
}
}
}
int main()
{
init();
int casesum=0;
{
printf("Case %d: ", ++casesum);
solve();
}
return 0;
}


solution

solution

### H - Treasure Hunt

solution

#include <bits/stdc++.h>
using namespace std;

#define x first
#define y second
typedef long double LD;
const LD eps=1e-15;
const LD inf=1e18;

struct Point:public pair<LD, LD>
{

Point(LD _x=0, LD _y=0):pair(_x, _y){}

Point& operator += (Point c)
{
x+=c.x; y+=c.y;
return *this;
}

Point& operator /= (LD c)
{
x/=c; y/=c;
return *this;
}

Point& operator -= (Point c)
{
x-=c.x; y-=c.y;
return *this;
}

Point operator + (Point c)
{
return Point(x+c.x, y+c.y);
}

Point operator - (Point c)
{
return Point(x-c.x, y-c.y);
}

Point operator * (LD c)
{
return Point(x*c, y*c);
}

Point operator / (LD c)
{
return Point(x/c, y/c);
}

bool zero()
{
return (fabs(x)<eps && fabs(x)<eps);
}

void rotate(LD angle)
{
LD tmp=x;
x=-sin(angle)*y+cos(angle)*tmp;
y=sin(angle)*tmp+cos(angle)*y;
}
};

Point origin;
LD angle;
Point pos[10], rec[10], ans[10];

inline LD sqr(LD x)
{
return x*x;
}
LD dis(Point b, Point c)
{
return sqrt(sqr(b.x-c.x)+sqr(b.y-c.y));
}
{
for (int i=1; i<=4; ++i) scanf("%Lf%Lf", &pos[i].x, &pos[i].y);
for (int i=1; i<=4; ++i) scanf("%Lf%Lf", &rec[i].x, &rec[i].y);
for (int i=1; i<=4; ++i)
if (fabs(pos[i].x)>eps || fabs(pos[i].y)>eps) return true;
for (int i=1; i<=4; ++i)
if (fabs(rec[i].x)>eps || fabs(rec[i].y)>eps) return true;
return false;
}
void rotate()
{
origin=Point(0, 0);
for (int i=1; i<=4; ++i) origin+=rec[i];
origin/=4;
for (int i=1; i<=4; ++i)
{
rec[i]-=origin;
pos[i]-=origin;
}
Point arrow=rec[2]-rec[1];
angle=atan2(arrow.y, arrow.x);
for (int i=1; i<=4; ++i)
{
rec[i].rotate(-angle);
pos[i].rotate(-angle);
}
}
void solve()
{
rotate();
Point total=Point(0, 0);
Point boundx=Point(inf, -inf), boundy=Point(inf, -inf);
for (int i=1; i<=4; ++i) total-=pos[i];
for (int i=1; i<=4; ++i)
{
boundx.x=min(rec[i].x, boundx.x);
boundx.y=max(rec[i].x, boundx.y);
boundy.x=min(rec[i].y, boundy.x);
boundy.y=max(rec[i].y, boundy.y);
}

for (int i=1; i<=4; ++i)
{
Point bound=Point((total.x<0? boundx.x:boundx.y), (total.y<0? boundy.x:boundy.y));
Point tmp=bound-pos[i];
LD rate=min(LD(1.0), min(tmp.x/total.x, tmp.y/total.y));
tmp=pos[i]+total*rate;
total-=tmp-pos[i];
pos[i]=tmp;
}

for (int i=1; i<=4; ++i)
{
pos[i].rotate(angle);
pos[i]+=origin;
}
for (int i=1; i<=4; ++i) printf("%.12Lf %.12Lf\n", pos[i].x, pos[i].y);
puts("");
}
{
for (int i=1; i<=4; ++i) scanf("%Lf%Lf", &ans[i].x, &ans[i].y);
for (int i=1; i<=4; ++i) answer+=dis(ans[i], pos[i]);
}
int main()
{
return 0;
}


### I - Truchet Tiling

solution

#include <bits/stdc++.h>
using namespace std;

const double PI=acos(-1);
const int maxn=110;

int n, m;
int dsu[maxn*maxn*4];
double area[maxn*maxn*4];
bool Map[maxn][maxn];
int pos[maxn*2][maxn*2];

{
scanf("%d%d", &n, &m);
for (int i=1; i<=n*m*3; i+=3)
{
dsu[i]=dsu[i+1]=dsu[i+2]=-1;
area[i]=area[i+2]=PI/4;
area[i+1]=2*2-PI/2;
}
for (int i=1; i<=n; ++i)
for (int j=1; j<=m; ++j)
scanf("%1d", &Map[i][j]);
}
int dsu_find(int cur)
{
return (dsu[cur]<0? cur:(dsu[cur]=dsu_find(dsu[cur])));
}
void merge(int u, int v)
{
u=dsu_find(u);
v=dsu_find(v);
if (u==v) return;
if (dsu[u]>dsu[v]) swap(u, v);
dsu[u]+=dsu[v];
dsu[v]=u;
area[u]+=area[v];
}
void divide()
{
for (int i=1; i<=n; ++i)
for (int j=1; j<=m; ++j)
{
int cur=((i-1)*m+j-1)*3;
if (i!=1)
{
int nx=((i-2)*m+j-1)*3;
if (Map[i][j]==Map[i-1][j])
{
merge(nx+2, cur+1);
merge(nx+3, cur+2);
}
else
{
merge(nx+3, cur+1);
merge(nx+2, cur+2);
}
}
if (j!=1)
{
int nx=((i-1)*m+j-2)*3;
if (Map[i][j])
{
if (Map[i][j-1])
{
merge(nx+1, cur+2);
merge(nx+2, cur+3);
}
else
{
merge(nx+2, cur+2);
merge(nx+3, cur+3);
}
}
else
{
if (Map[i][j-1])
{
merge(nx+1, cur+1);
merge(nx+2, cur+2);
}
else
{
merge(nx+2, cur+1);
merge(nx+3, cur+2);
}
}
}
}
}
void calc_pos()
{
for (int i=1; i<=n; ++i)
for (int j=1; j<=m; ++j)
{
pos[(i-1)*2][j*2-1]=pos[i*2-1][(j-1)*2]=pos[i*2-1][j*2]=pos[i*2][j*2-1]=0;
if (Map[i][j])
{
pos[(i-1)*2][j*2]=((i-1)*m+j-1)*3+1;
pos[(i-1)*2][(j-1)*2]=pos[i*2-1][j*2-1]=pos[i*2][j*2]=((i-1)*m+j-1)*3+2;
pos[i*2][(j-1)*2]=((i-1)*m+j)*3;
}
else
{
pos[(i-1)*2][(j-1)*2]=((i-1)*m+j-1)*3+1;
pos[(i-1)*2][j*2]=pos[i*2-1][j*2-1]=pos[i*2][(j-1)*2]=((i-1)*m+j-1)*3+2;
pos[i*2][j*2]=((i-1)*m+j)*3;
}
}
/*
for (int i=0; i<=n*2; ++i, putchar('\n'))
for (int j=0; j<=m*2; ++j)
printf("%d ", pos[i][j]);
*/
}
void solve()
{
calc_pos();
divide();
int T;
scanf("%d", &T);
while (T--)
{
int x, y;
scanf("%d%d", &x, &y);
if (pos[x][y]==0) printf("%.4lf\n", 0.0);
else printf("%.4lf\n", area[dsu_find(pos[x][y])]);
}
}
int main()
{
int casesum;
scanf("%d", &casesum);
for (int i=1; i<=casesum; ++i)
{
printf("Case %d:\n", i);
solve();
}
return 0;
}


### J - As Long as I Learn, I Live

solution

posted @ 2018-11-01 23:00  GerynOhenz  阅读(66)  评论(0编辑  收藏