2014-01-04
■ JOI contest
2つ決定勢は無視でき、0個決定勢は貪欲に決定でき、またチームCの得点も確定できるため
1つ決定勢のみ考慮する。これは「いくつCを超えるか」を決めうちすれば貪欲でできる。
vectorのiteratorの使い方さえわかれば簡単です(白目)
//Daily Lunch Special Tanoshii !! #include#include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef pair<int,int> P; typedef pair<int,P> P1; typedef pair P2; typedef long long ll; #define pu push #define pb push_back #define mp make_pair #define eps 1e-7 #define INF 2000000000 #define s(x) scanf("%d",&x) #define rep(i,x) for(int i=0;i
int v[3005]={}; int m[3005]={}; vector<int>vec; vector<int>one; vector<int>cpy; int main() { int n,k; scanf("%d %d",&n,&k); for(int i=0;i<2*n;i++) { int x,y; scanf("%d %d",&x,&y); if(!y) vec.pb(x); else { v[y]+=x; m[y]++;} } sort(vec.begin(),vec.end()); while(m[k]!=2){ m[k]++; v[k]+=vec[vec.size()-1]; vec.pop_back();} int add=0; for(int i=1;i<=n;i++) { if(m[i]==1) one.pb(v[i]); if(m[i]==2 && v[i]>v[k]) add++; } sort(one.begin(),one.end()); for(int i=0;i<6005;i++) cpy.pb(i); int ret=INF; //cout << vec.size() << " " << one.size() << endl; for(int i=0;i<=one.size();i++) { bool u[6005]={}; int res=i; for(int j=0;j1 -j]=true; } vector<int>val(0); vector<int>num=cpy; while(!num.empty() && num[num.size()-1]>vec.size()-1-i) num.pop_back(); cpy=num; for(int j=0;jint f=upper_bound(vec.begin(),vec.end(),v[k]-one[j])-vec.begin(); int d=lower_bound(num.begin(),num.end(),f)-num.begin(); vector<int>::iterator it=lower_bound(num.begin(),num.end(),f); d--; if(d==-1) goto fail; it--; u[num[d]]=true; num.erase(it); } for(int j=0;j if(u[j]) continue; u[j]=true; vector<int>::iterator it=lower_bound(num.begin(),num.end(),j); num.erase(it); int f=upper_bound(vec.begin(),vec.end(),v[k]-vec[j])-vec.begin(); int d=lower_bound(num.begin(),num.end(),f)-num.begin(); it=lower_bound(num.begin(),num.end(),f); d--; if(d==-1) { u[num[num.size()-1]]=true; num.pop_back(); res++; } else {it--;u[num[d]]=true;num.erase(it);} } ret=min(ret,res); fail:; } ret+=1+add; cout << ret << endl; }
■ JOIの幾何
Belt,Nightman,Ruinsです。
体感難易度はNightman< Ruins < Belt atan2して角度とイベントを対応づける。次にソートして順に見ていく。 P2;
typedef long long ll;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 2000000000
#define s(x) scanf("%d",&x)
#define rep(i,x) for(int i=0;i Nightman WFフェーズは自明で、平面走査もやるだけ... まあ難しいけど... あとepsの重要さを再確認した問題になりました(epsを0->1e-7にしただけで75->100になった) P2;
typedef long long ll;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 2000000000
#define s(x) scanf("%d",&x)
#define rep(i,x) for(int i=0;i z(idx+1);
for(int i=0;i<1005;i++)
{
for(int j=0;j<1005;j++)
{
if(za[i][j])
{
z[za[i][j]]=mp(i,j);
}
}
}
for(int i=0;i<225;i++)for(int j=0;j<225;j++)d[i][j]=1e8;
d[0][0]=0;
for(int i=1;i<=idx;i++)
{
for(int j=1;j<=idx;j++)
{
if(i==j){ d[i][j]=0; continue;}
int x1=z[i].first;
int y1=z[i].second;
int x2=z[j].first;
int y2=z[j].second;
if(y1>y2)
{
swap(x1,x2); swap(y1,y2);
}
for(int k=0;kif(x1==x2)
{
if(!(s[k] はじめは使う辺を決めうちして、そこから適当にDPするとしていてO(N^5)でデデドン(絶望) としていましたが使う辺じゃなくて左端の点を決めうちするだけでよいと分かり、O(N^4)になる。 N<=128だけど定数倍軽い(?)ので余裕で通る。 P2;
typedef long long ll;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define s(x) scanf("%d",&x)
#define rep(i,x) for(int i=0;i
#include
//Daily Lunch Special Tanoshii !!
#include
//Daily Lunch Special Tanoshii !!
#include