此次考得不怎麼樣,只有200分!
node
這題水水水!
這題就是一道循環題嘛!
直接一邊循環一邊作就行了!數組
這題我是直接暴力的。spa
這題就是求至少用多少條通過(x0,y0)的不一樣直線能把全部輸入的點(恐怖分子)都通過。3d
我一開始認爲這道題很難——怎麼判斷幾個點是否在同一條直線上?code
通過個人左思右想,終於發現,只要兩個點的最簡形式(即X、Y座標都除以它們的最大公約數後的值)相等,它們就在同一條直線上。blog
而後就直接暴力掃一遍,找到一個還沒死的恐怖分子就把他所在的直線上的全部恐怖分子殺死。最後統計一下答案就行了。遞歸
建議你們把圖平移一下,使激光武器移動到(0,0)的位置(即把全部點的X座標減去激光武器的X,Y座標減去激光武器的Y),並一開始先把那些X爲0或Y爲0的恐怖分子先殺掉。io
PS:Dev.C++ 5.8.3 和 Free Pascal 都有個BUG!當源文件名爲gun.cpp或gun.pas時,就會運行超慢,HelloWorld也要運行個3~4秒,誰能告訴我爲何?class
但我比賽時判斷得不周到,錯了。。。變量
比賽時我認爲這又是找規律題了,列個表格就能找到規律,而後無腦實現代碼。
我便畫了一個表格,1 1 1,2 1 1,2 2 1 地寫,結果花了半小時,仍是沒有找到規律(呵呵,2 2 1已經有63種連法了,孩紙你慢慢畫吧)
後來王泓皓本身想到正解AC了,何燁成參照題解AC了。
我才知道此題要用遞推!
王泓皓看題解時,發現了一下兩行文字:
動態規劃:
f[i][j]表示一種顏色i個,另外一種顏色j個此時有多少種方法
而後他就關閉了題解,本身找規律去了,王泓皓就畫了一個相似於下圖的圖。
從任意一個島嶼斷開這個島鏈,咱們就會驚奇地發現,島嶼是這樣排列的(ABC分別表示三種顏色的島嶼):
A-B-C-A-B-C-A-B-C……
而後就能夠發現,若是把相同顏色的島嶼分紅一堆(每種顏色的一大坨中都包含了許多個那種顏色的島嶼),最後的每一種鏈接方式都是這樣的(不必定會有那麼多或只有那麼多的橋哦!):
SO,最後的答案就是紅藍兩色間的鏈接方案 × 藍紫兩色間的鏈接方案 × 紅紫兩色間的鏈接方案
那麼怎麼求兩色間的鏈接方案呢?
設F[i][j]表示第一種顏色(在左邊)有i個島嶼,第二種顏色(在右邊)有j個島嶼,其中第二種島嶼中的j是剛加入的島嶼。
那很明顯,F[i][j]=F[i][j-1]+某個數 了。
那加上的那個數又是多少呢?
很明顯,如今咱們要求的那個數是必須鏈接右邊第j個島嶼的鏈接方案,也就是左邊第1個島嶼鏈接右邊第j個島嶼,第2個島嶼鏈接第j個島嶼,第3個島嶼鏈接第j個島嶼……第i個島嶼鏈接第j個島嶼。
但每一次咱們強制讓兩個島嶼相連時,剩下的島嶼怎麼辦?因爲每次強制鏈接的都是左邊的1個島嶼和右邊的1個島嶼,剩下的島嶼可連可不連,那剩下的島嶼的鏈接方案很顯然就是F[i-1][j-1]了。因爲咱們能夠強制鏈接i座島嶼,因此**加上的那個數就是 F[i-1][j-1]*i 了**。
最後輸出F[a][b]F[a][c]F[b][c]就行了。
PS:注意要模上 998244353 哦!這裏但是有一個大坑的!全部的F[0][i]和F[i][0]所有賦值爲1!
這題我用DFS+貪心,結果就DIE了
正解是 二分答案 ,如今還在思考如何判斷二分到的答案是否合法。。。
首先,我必須申明一下:二分不是最難辦的,判斷二分出來的答案是否正確纔是最難辦的!!!
某位同窗就發現了這個規律(圖中的X,Y表示一個快遞員在X的位置上,另外一個在Y的位置上),判斷時能夠用遞歸,從上一層某個地方連了一條線到下一層某個地方表示當上一層的那個地方成立(兩個快遞員間的距離小於等於二分到的答案時)時,才能夠繼續判斷下一層的那個地方(也就是判斷從X,Y出發,是否能夠走到第N行,即完成):
可是,咱們會發現,重複地判斷一個地方是會超時滴(如第1層的S1,X1和S2,X1合法,就會都去判斷X1,X2,致使判斷了兩次X1,X2)
怎麼辦呢?
開一個BZ數組,BZ[x][y]記錄有沒有判斷過x,y明顯是不行的,題目中說得清清楚楚,0≤xi≤10^9,開一個 的標記數組很明顯是會爆炸的;
咱們就要用X[0]和X[-1]來表示S1和S2了。
以後開一個BZ數組,BZ[x][y]記錄有沒有判斷過X[x],X[y]行嗎?
不行!題目中也有這麼一句話:100000,開一個10,000,000,000大小的數組不做死嗎?
那怎麼辦?咱們再仔細看看圖唄!
其實不難發現,到了第i行時,每次判斷都有包含X[i],因此這一行中,只要有一個地方是合法的,那麼就能夠遞歸到X[i],x[i+1]這個位置。
咱們能夠開一個數組BZ(怎麼又是它?!),BZ[i]表示第i行是否有遞歸到下一層的X[i],X[i+1](就是第i行有沒有合法的)
但這樣作仍會時超。。。
咱們又能夠發現一個神奇的規律:搜索列比搜索行更快!
並且咱們的程序跑得慢還有一個緣由——已經搜索到最底層了,回溯後卻又繼續遞歸!
咱們能夠用一個變量記錄是否到達最底層,若是發現已經到達過最底層了,就返回上一層!
此次比賽仍是至關有質量的,題目都挺坑。
此次仍是比較粗心,下次要審清楚題提,認真思考了!
T1:
#include<cstdio> using namespace std; #define time 86400 int main() { freopen("read.in","r",stdin); freopen("read.out","w",stdout); int a,n,i,t; scanf("%d%d",&n,&t); for(i=1;i<=n;i++) { scanf("%d",&a); t=t+a-time; if(t<=0) break; } printf("%d\n",i); return 0; }
T2:
#include<cstdio> #include<cmath> using namespace std; struct node { int x,y; }a[1001],min; bool dead[1001]; int s[5001]; bool pd(node n1,node n2) { if(n1.x>n2.x) return 1; if(n1.x<n2.x) return 0; if(n1.y>n2.y) return 1; return 0; } bool zhi(int x) { int tt=sqrt(x),i; for(i=2;i<=tt;i++) { if(x%i==0) return 0; } return 1; } int abs(int x) { if(x<0) return 0-x; return x; } void qsort(int l,int r) { int i=l,j=r; node mid=a[(l+r)/2],t; while(i<=j) { while(pd(mid,a[i])) i++; while(pd(a[j],mid)) j--; if(i<=j) { t=a[i]; a[i]=a[j]; a[j]=t; i++;j--; } } if(i<r) qsort(i,r); if(l<j) qsort(l,j); } int main() { freopen("gun.in","r",stdin); freopen("gun.out","w",stdout); int n,xx,yy,i,j,sum=0,ans=0; bool b1=0,b2=0; scanf("%d%d%d",&n,&xx,&yy); for(i=1;i<=n;i++) { scanf("%d%d",&a[i].x,&a[i].y); a[i].x-=xx,a[i].y-=yy; } //qsort(1,n); for(i=2;i<=10000;i++) { if(zhi(i)) s[++sum]=i; } for(i=1;i<=n;i++) { //printf("%d %d\n",a[i].x,a[i].y); if(a[i].x==0) dead[i]=b1=1; else if(a[i].y==0) dead[i]=b2=1; } if(b1) ans++; if(b2) ans++; for(i=1;i<=n;i++) if(!dead[i]) { dead[i]=1;ans++; min=a[i]; for(j=1;j<=sum;j++) { if(zhi(min.x)&&zhi(min.y)&&min.x!=min.y) break; if(min.x<s[j]&&min.y<s[j]) break; while((min.x>=s[j]||min.y>=s[j])&&min.x%s[j]==0&&min.y%s[j]==0) { min.x=min.x/s[j]; min.y=min.y/s[j]; } } //printf("%d:%d\t%d\n",i,min.x,min.y); for(j=1;j<=n;j++) if(!dead[j]) { if(a[j].x%min.x==0&&a[j].y%min.y==0&&abs(a[j].x)>=min.x&&abs(a[j].y)>=min.y&&a[j].x/min.x==a[j].y/min.y) dead[j]=1; } } printf("%d\n",ans); return 0; }
T3:
#include<cstdio> using namespace std; #define MOD 998244353 long long f[5001][5001]; int main() { freopen("love.in","r",stdin); freopen("love.out","w",stdout); int a,b,c,i,j;long long x,y; scanf("%d%d%d",&a,&b,&c); for(i=0;i<=5000;i++) f[i][0]=f[0][i]=1; for(i=1;i<=5000;i++) { for(j=1;j<=5000;j++) { f[i][j]=(f[i][j-1]+(i*f[i-1][j-1])%MOD)%MOD; } } x=(f[a][b]*f[b][c])%MOD; y=(x*f[a][c])%MOD; printf("%lld\n",y); return 0; }
T4:
#include<cstdio> using namespace std; //__attribute__((optimize("-O2"))) bool b[100010]; int a[100010],n,max,want; int abs(int x) { if(x<0) return 0-x; return x; } void check(int k,int i)//k<i { if(max==n||abs(a[k]-a[i])>want) return; if(i>max) max=i; check(k,i+1); if(b[i]) { b[i]=false; check(i,i+1); } } int main() { freopen("delivery.in","r",stdin); freopen("delivery.out","w",stdout); int ans,i,x,y,j,l=0,r,mid; scanf("%d%d%d",&n,&x,&y); if(x>y) r=x; else r=y; for(i=1;i<=n;i++) { scanf("%d",&a[i+1]); if(a[i+1]>r) r=a[i+1]; } a[0]=x,a[1]=y; while(l<=r) { mid=(l+r)/2; if(mid<abs(x-y)) { l=mid+1; continue; } for(i=0;i<=n;i++) b[i]=1; max=-1;want=mid; check(0,1); if(max==n) { r=mid-1; ans=mid; } else l=mid+1; } printf("%d\n",ans); return 0; }