487做的不錯……
第一題是這么一個題,給出一個序列N(N<=50),你可以選擇距離恰好為L的兩個數,取出來求和(每個數只能用一次),求取法讓和最大
乍一看有點蒙,實際上,這N個數可以按照對L+1同余分類,這樣就分出了若干類,然后每類里數肯定<=25,在2S的時間內用2^25的方法搜索即可……
489的300是這么個問題:給你N類球(N<=50),和一張N*N的轉移表,某臺機器的功能就是:扔進若干球(數量不定,每個球都屬于這N類),隨機取兩個出來,根據轉移表合成出一個……直到只有一個球,問對于給定的輸入,輸出能否確定……
聽起來很玄的題…我當時猜測的結論是:由少許幾個球的情況可以產生所有情況,于是就枚舉+驗證,剛開始猜測的是3~4個,結果4個TLE,3個大概過了……水了下,對了……
500是個規律題……但是我沒找到規律……悲劇了……
rating-=13,1522……
第一題是這么一個題,給出一個序列N(N<=50),你可以選擇距離恰好為L的兩個數,取出來求和(每個數只能用一次),求取法讓和最大
乍一看有點蒙,實際上,這N個數可以按照對L+1同余分類,這樣就分出了若干類,然后每類里數肯定<=25,在2S的時間內用2^25的方法搜索即可……
1 public class BunnyComputer
2 {
3 int dfs(int[] arr,int now,int k)
4 {
5 if (now+k>=arr.length) return 0;
6 int notTake=dfs(arr,now+k,k);
7 int take=arr[now]+arr[now+k]+dfs(arr,now+k+k,k);
8 return take>notTake?take:notTake;
9 }
10 public int getMaximum(int[] preference, int k)
11 {
12 k++;
13 int ans=0;
14 for (int i=0;i<k;i++)
15 ans+=dfs(preference,i,k);
16 return ans;
17 }
18 }
水了這么一道,rating->1535,黃了……2 {
3 int dfs(int[] arr,int now,int k)
4 {
5 if (now+k>=arr.length) return 0;
6 int notTake=dfs(arr,now+k,k);
7 int take=arr[now]+arr[now+k]+dfs(arr,now+k+k,k);
8 return take>notTake?take:notTake;
9 }
10 public int getMaximum(int[] preference, int k)
11 {
12 k++;
13 int ans=0;
14 for (int i=0;i<k;i++)
15 ans+=dfs(preference,i,k);
16 return ans;
17 }
18 }
489的300是這么個問題:給你N類球(N<=50),和一張N*N的轉移表,某臺機器的功能就是:扔進若干球(數量不定,每個球都屬于這N類),隨機取兩個出來,根據轉移表合成出一個……直到只有一個球,問對于給定的輸入,輸出能否確定……
聽起來很玄的題…我當時猜測的結論是:由少許幾個球的情況可以產生所有情況,于是就枚舉+驗證,剛開始猜測的是3~4個,結果4個TLE,3個大概過了……水了下,對了……
public class BallsConverter{
int[][] arr;
int n;
int work(int[] now,int n){
if (n==1) return now[0];
int[] next=new int[n-1];
int[] ans=new int[n-1];
for (int i=0;i<n-1;i++){
for (int j=0;j<n-1;j++)
next[j]=now[j];
next[i]=arr[now[i]][now[n-1]];
ans[i]=work(next,n-1);
}
for (int i=1;i<n-1;i++){
if (ans[i]!=ans[0]) return -2;
}
return ans[0];
}
public String theGood(String[] convent){
n=convent.length;
arr=new int[n][n];
for (int i=0;i<n;i++){
for (int j=0;j<n;j++){
char tmp=convent[i].charAt(j);
if (tmp>='A' && tmp<='Z')
arr[i][j]=tmp-'A';
else
arr[i][j]=tmp-'a'+26;
}
}
for (int t1=0;t1<n;t1++)
for (int t2=0;t2<n;t2++)
for (int t3=0;t3<n;t3++)
{
int[] tmp=new int[3];
tmp[0]=t1; tmp[1]=t2; tmp[2]=t3;
int ans=work(tmp,3);
if (ans==-2) return "Bad";
}
return "Good";
}
}
經刁哥教育,我明白了,這個東西實際上是這個意思,如果這個東西滿足結合律,則順序無關緊要了,可以直接從頭到尾合并算出……也就確定了……于是檢驗結合律相當于檢驗arr[i][arr[j][k]]==arr[arr[i][j]][k]……int[][] arr;
int n;
int work(int[] now,int n){
if (n==1) return now[0];
int[] next=new int[n-1];
int[] ans=new int[n-1];
for (int i=0;i<n-1;i++){
for (int j=0;j<n-1;j++)
next[j]=now[j];
next[i]=arr[now[i]][now[n-1]];
ans[i]=work(next,n-1);
}
for (int i=1;i<n-1;i++){
if (ans[i]!=ans[0]) return -2;
}
return ans[0];
}
public String theGood(String[] convent){
n=convent.length;
arr=new int[n][n];
for (int i=0;i<n;i++){
for (int j=0;j<n;j++){
char tmp=convent[i].charAt(j);
if (tmp>='A' && tmp<='Z')
arr[i][j]=tmp-'A';
else
arr[i][j]=tmp-'a'+26;
}
}
for (int t1=0;t1<n;t1++)
for (int t2=0;t2<n;t2++)
for (int t3=0;t3<n;t3++)
{
int[] tmp=new int[3];
tmp[0]=t1; tmp[1]=t2; tmp[2]=t3;
int ans=work(tmp,3);
if (ans==-2) return "Bad";
}
return "Good";
}
}
500是個規律題……但是我沒找到規律……悲劇了……
rating-=13,1522……