① 杭電acm1007
我看了你的代碼,但是有些地方不懂,不過可以知道的是,你不知道題目猜數字其實就是用二分法進行猜,不是你一次if就能計算出結果的。要用for循環或者用對數進行計算。
參考代碼AC:
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int n,t,s,i,m;
while(cin>>n)
{
t=1;
s=0;
m=n;
for(i=1;n>t;i++){//其實就是一棵樹
s+=i*t;
n-=t;
t*=2;
}
s+=n*i;
printf("%.2lf\n",(double)1.0*s/m);
}
return 0;
}
② OJ貪心演算法,活動安排,求大神解答
按結束時間從小到大排序,之後從開始貪心即可
③ 求python三位水仙花數OJ題和答案
print(str([iforiinrange(100,1000)if(i%10)**3+(i//10%10)**3+(i//100)**3==i])[1:-1])
一行代碼帶走
如果不想要最後的換行,則用下面這句
print(str([iforiinrange(100,1000)if(i%10)**3+(i//10%10)**3+(i//100)**3==i])[1:-1],end='')
④ 求教兩道杭電OJ上的ACM題,貪心演算法的
兩個問題有共同的地方就是他們都要個排序的標准啊
1789的標準是扣分的多少
而2037的標準是節目上演時間的長短
排序之後再進行從最優的選擇開始進行挑選(挑完後做個標記)避免重復 一下是我的程序
(我也是初學者 寫的不太好請諒解)
1789
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int main(void)
{
int n,m,temp,sum,i,j,h,x;
int su [1009];
int su1[1009];
int su2[1009];
while(cin>>n)
{
while(n--)
{
sum=0;
cin>>m;
for(i=1;i<=m;i++)
su[i]=i;
for(i=1;i<=m;i++)
cin>>su1[i];
for(i=1;i<=m;i++)
cin>>su2[i];
for(i=1;i<=m-1;i++)
for(j=i+1;j<=m;j++)
if(su2[i]<su2[j])
{
temp=su1[i];
su1[i]=su1[j];
su1[j]=temp;
temp=su2[i];
su2[i]=su2[j];
su2[j]=temp;
}
for(i=1;i<=m;i++)
{
h=0;
for(x=su1[i];x<=m;x++)
{
if(su[x]==0)
{ h=1;
break;
}
}
if(h==0)
for(j=su1[i];j<=m;j++)
su[j]--;
else
sum+=su2[i];
}
cout<<sum<<endl;
}
}
return 0;
}
2037
#include<iostream>
using namespace std;//根據上演電視劇時間的長短來排序越短越合算
int main(void)
{
int n,i,j,h,x,count,temp;
int su[200];
int su1[200];
int su2[200];
while(cin>>n&&n)
{
count=0;
for(i=1;i<=200;i++)
su[i]=1;
for(i=1;i<=n;i++)
cin>>su1[i]>>su2[i];
for(i=1;i<=n-1;i++)
for(j=i+1;j<=n;j++)
if((su2[i]-su1[i])>=(su2[j]-su1[j]))
{
temp=su2[i];
su2[i]=su2[j];
su2[j]=temp;
temp=su1[i];
su1[i]=su1[j];
su1[j]=temp;
}
for(i=1;i<=n;i++)
{ h=0;
for(j=su1[i];j<su2[i];j++)
if(su[j]<=0)
{ h=1;
break;
}
if(h==0)
{for(x=su1[i];x<su2[i];x++)
su[x]--;
count++;
}
}
cout<<count<<endl;
}
return 0;
}
⑤ oj最小值 給出一個n個數的數列詢間
你是要一個演算法吧?
我想了半天,只有一個 O(n^2) 的演算法,而且要假設 a[i] 都是正數(如果有正有負就太麻煩了).
這個可以叫動態規劃演算法,也可以什麼都不叫,因為它就是個最簡單的動態規劃.
總的思路:
r 從 1 到 n,對每個 r,在前 r 個數:a[1],a[2],...,a[r] 中,求:
在所有以 r 結尾的區間 [k,r](其中 k = 1,2,...,r)中,f(k,r) = a[p]*(a[k]+a[k+1]+...+a[r]) 中最大的那個.
這樣,總的最大值(即題目所求)就是所有 r 從 1 到 n 中最大的那個.
首先我們造一個輔助序列:S[r] = a[1]+a[2]+...+a[r]
這樣對任意的 k,我們就能在 O(1) 時間算出:a[k]+a[k+1]+...+a[r] = S[r] - S[k-1]
然後,對每個 r,定義一個 M 序列:
如果 a[k] 是 a[k],a[k+1],...,a[r] 中的最小值,那麼就把 k 放進 M 序列中.
k 也是從右往左依次放入 M 序列,所以 M[1] < M[2] < ...< M[T(r)] = r,其中 T(r) 是 M 序列的長度.
對於 M 中的一個數:M[i],所有以 M[i] 為最小值的序列中,f 值最大的一個是從 M[i-1]+1 到 r 的序列:
a[M[i]] * (a[M[i-1]+1] + a[M[i-1]+2] + ...+ a[r]) = a[M[i]] * (S[r] - S[M[i-1]])
所以,我們只要對每個 M 中的值,都算出:a[M[i]] * (S[r] - S[M[i-1]]),取最大的一個就行了.
當我們從 r 到 r+1 時,需要更新 M 序列.
只需將 a[r+1] 分別與 a[M[T(r)]],a[M[T(r)-1]],...相比,如果 a[r+1] 小,就把舊的 M 序列中的數刪掉,最後在 M 序列的末尾添上 r+1 即可.
時間復雜度:
對每個 r,其 M 序列最多有 O(n) 個數,每個 a[M[i]] * (S[r] - S[M[i-1]]) 都可以在 O(1) 時間算出,所以最後是 O(n^2)
關於更多的思考.
能否優化:能,但並不改變 O(n^2) 的時間復雜度.
假設第 r 步時,M[i] 是 f 值最大的那個.
那麼在後面的 r+1,r+2,...步時,只要 M[i] 還在 M 序列中,那麼 M[i] 的 f 值永遠比 M[1],M[2],...,M[i-1] 的 f 值大.
但 M[i] 可能從 M 序列中刪掉,這樣的話,M[1],M[2],...,M[i-1] 就又可能成為最大的 f 值了.
所以優化是這樣:給 M 序列造一個輔助序列 flag,如果 M[i] 曾經取到最大 f 值,那麼 flag[i] = 1,否則 flag[i] = 0.
這樣我們不需要對所有的 M[i] 計算 f 值,只要(在 M 序列中)從右到左依次計算 M 值,直到碰到第 1 個 flag[i] = 1 的即可.
就說這么多了,如果對哪個細節不清楚,就追問一下吧.
⑥ 杭電acm2178
首先,猜數字是不能亂猜的。肯定要找到一定的方法來猜的!
要猜到最大的數字m,也就是說,在1到m間的每一個數,你都能在n次內把它猜出來!
所以說在最壞的情況下,在1到m間,你最多隻要猜log2(m)+1(取整)次,所以m=2^n-1.即猜n次,你能猜到的最大的數為2^n-1.
#include<stdio.h>
int main()
{
int t, n, m;
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
m = 1;
while (n--) m <<= 1;
printf("%d\n", m-1);
}
return 0;
}
⑦ oj上的C語言題目,帶小數的高精度演算法
沒必要一定要用小數,用整數來計算,同時統計小數點應該在的位數。
然後輸出的時候按字元輸出,把點.放在對應的輸出位上面。
浮點數總是有誤差的,要完全無誤差精度的話可能有點問題。
代碼的話你自己實現吧,應該還是比較簡單的,oj的題目代碼還是得自己敲的
⑧ 請教編程高手:如何培養編寫演算法的思路
選一本出色的教材.有條件就看英文的,然後給自己一個環境,例如LINUX+GCC+GDB,用純粹的語言去在解決問題的過程中學習演算法.
沒有目的性去學習,往往效率不高,可以找一些ONLINE JUDGE的題目做做.例如Welcome To PKU JudgeOnline,對著裡面的問題,先自己思考,嘗試編程解決,如果不能解決,就翻翻演算法書,想想為什麼.
如果還是不行,那就上網看看別人有沒有解決掉,怎麼做,看看他們用到什麼演算法,比對著,然後進一步自己去實現.
有時候對於演算法的問題的實現,你在實現之前也許會卡住,但是在編程過程中,隨著你的鍛煉和熟練度的提高.會有那麼一天你覺得什麼都通了,而且,你是在用的過程中學習.堅持走下去,一定事半功倍.
「cracking the coding interview」,題目是按照array, stack&queue, 鏈表,樹圖,遞歸這種章節安排的,每章節題目7-8個,不多,難度中等,找感覺很有幫助。第一遍自己寫不出來的話(我就是,這么弱!),畫圖分析,抄背默。一遍做完再做一遍,第二遍就快很多,理解也深刻了,所謂讀書百遍,其意自現,演算法也一樣。
不要一開始就看《演算法導論》,這本書有太多關於演算法的數學證明.
推薦你看看這本:演算法(第4版) (豆瓣),作者是高德納的學生:塞奇威克 (Robert Sedgewick)
書中演算法代碼主要是用Java編寫,裡面有大量的圖來讓你明白例如:排序,查找,樹和圖的演算法運行過程。
這本書的目錄編排也很清晰,他就告訴你演算法主要就可以分為:排序,查找,圖和字元串。從這4個方面可以演化出很多演算法,最關鍵是:這本書的作者不但是在告訴你what,而且告訴你why(分析各種演算法的優缺點)
這本書其他好的地方
比如講到快速排序,很多書可能講了快速排序的原理就完了。但這本書就直接講了原始的快速排序可以改進的地方:1. 在小數組上,切換到插入排序;2. 三取樣切分;3. 三向切分的快速排序。
優先隊列怎麼和排序演算法扯上關系呢?其實優先隊列就是可以用堆排序來實現,堆排序的時間復雜度和快速排序是一樣的,但是實際中為什麼堆排序的運行時間要比快速排序多呢?因為這和CPU的Cache命中率有關系,堆排序不符合演算法運行的局部性原則
比如書中2.5節,講了排序演算法的實際用途,這本書不光告訴你演算法的原理,還告訴你演算法的用途。
⑨ oj最簡單的題目
注意題目要求從小到大輸出
if(a[i]!=a[j])
k++;
if(k==n)
{ a[n]=b[j];
n++;
}
這段代碼有問題
給你一組數據,你自己調吧
3 4
5 6 8
4 6 7 8
⑩ 為什麼我在OJ上做得水仙花數的題總是wrong answer
樓主,這三個式子錯了
a=i/100;
b=i%100/10;
c=i%100%10;
修改如下
#include<stdio.h>
int main()
{
int m,n,i,a,b,c,d=0;
scanf("%d %d",&m,&n);
while(m!=0&&n!=0)
{
if(m>=100&&n<=999)
for(i=m;i<=n;i++)
{
a=i/100;
b=i/10-a*10;
c=i%10;
if(i==a*a*a+b*b*b+c*c*c)
{
printf("%d ",i);d++;
}
}
if(m<n&&d==0)
printf("no\n");
else
printf("\n");
scanf("%d %d",&m,&n);
}
return 0;
}