acm常用演算法
⑴ acm總是超時,有簡單演算法嗎
當然有,首先求整除9的個數不需要一個個試,求含有9的也可以按位數遞歸。
//求某個正整數中,小於自身,且含有數字9或能被9整除的正整數的個數。
/*思路分析:
求含有數字9的總數 + 能被9整除的總數 - 既含有數字9又能被9整除的個數
具體思路:從高位到低位求含有數字9的范圍 - 此范圍內能被9整除的個數
還要 + 此范圍外的低位范圍內的結果(進行遞歸調用),
最後加上所有能被9整除的正整數個數。
如此可將大整數n劃分
*/
如下圖我先寫求整除9的函數,為保證字函數正確性,寫了一個暴力演算法進行比對。如下圖
#include<iostream>
usingnamespacestd;
#include<stdlib.h>
#include<time.h>
//求某個正整數中,小於自身,且含有數字9或能被9整除的正整數的個數。
/*思路分析:
求含有數字9的總數+能被9整除的總數-既含有數字9又能被9整除的個數
具體思路:從高位到低位求含有數字9的范圍-此范圍內能被9整除的個數
還要+此范圍外的低位范圍內的結果(進行遞歸調用),
最後加上所有能被9整除的正整數個數。
如此可將大整數n劃分
*/
//暴力驗證演算法
intsumOfDivided9_B(inta,intb){ //求介於a到b(不含b)之間的能被9整除的個數
intsum=0;
for(;a<b;a++){ //暴力演算法做驗證
if(0==a%9)sum++;
}returnsum;
}
//求介於a到b(不含b)之間的能被9整除的個數,(用戶需保證a<b)
intsumOfDivided9(constint&a,constint&b){
return(b-1)/9-(a-1)/9; //即1~b-1減去1~a-1
}
intmain(){
srand(time(0)); //隨機數種子
intcount=0; //錯誤的個數
for(inti=0;i<100;i++){
inta=rand(),b=a+1+rand()%10000; //隨機生成范圍,最多10000個數
intsum_B=sumOfDivided9_B(a,b); //暴力演算法
intsum_Q=sumOfDivided9(a,b); //快速演算法
if(sum_B!=sum_B){
cout<<"WRONG! ";
count++;
}elsecout<<"RIGHT√ ";
cout<<"(a="<<a<<")%9="<<a%9<<" (b="<<b<<")%9="<<b%9<<
" 暴力="<<sum_B<<" 快速="<<sum_Q<<endl;
}
cout<<"WRONGtotal="<<count<<endl;
system("pause");
}
未完待續!
⑵ 參加ACM大賽應該准備哪些課程
課程:
(1)基本演算法: 二分,分治,貪心
(2) 離散數學離散數學動態規劃
(3) 搜索演算法:深度優先 搜索,廣度優先搜A*演算法 ,阿爾法貝塔剪枝
(4)數據結構:線段樹, 樹狀數組,並查集,Trie圖
(5)圖論問題:最小生成樹 最短路 強連通分量、橋和割點
(6)網路流演算法:基本的網路流演算法,Dinic演算法,帶上下界的網路流,最小費用流
(7)計算幾何:線與線求交,線與面求交,求凸包,半平面求交等
(8) 離散數學,高等數學,線性代數,初等數論,計算幾何
(9)計算機專業英語
(10)C++;基礎的遞歸、枚舉演算法
(2)acm常用演算法擴展閱讀:
1.參賽隊伍最多由三名參賽隊員組成。
2.競賽中命題10題左右,試題描述為英文,比賽時間為5個小時,前四個小時可以實時看到排名,最後一小時封榜,無法看到排名。
3.競賽可以使用的語言:java, C, C++, Kotlin 和 Python。
4.重點考察選手的演算法和程序設計能力,不考察實際工程中常用的系統編程,多線程編程等等;
5.選手可攜帶任何非電子類資料,包括書籍和列印出來的程序等,部分賽區會對選手攜帶的紙質資料做限制。
6.評委負責將結果(正確或出錯的類型)通過網路盡快返回給選手,除此之外不提供任何額外幫助;
7.每個題目對應一種顏色的氣球,通過該題目的隊伍會得到對應顏色氣球。每道題目第一支解決掉它的隊還會額外獲得一個「FIRST PROBLEM SOLVED」的氣球。
⑶ acm中基本演算法有哪些
回溯演算法,貪心法,蠻力法,動態規劃,分支限界,圖演算法
⑷ 我是用的是C語言,想在黑龍江省ACM大賽中拿三等獎,應該掌握那些演算法……
當中有幾百種計算機常用的演算法的框架和模板,如果你還在為演算法問題而困擾時,這資料會讓你廓然開朗,我也在學,很有用所以極力推薦給你.
框架部分目錄如下:
圖論
路徑問題
0/1邊權最短路徑
BFS
非負邊權最短路徑(Dijkstra)
可以用Dijkstra解決問題的特徵
負邊權最短路徑
Bellman-Ford
Bellman-Ford的Yen-氏優化
差分約束系統
Floyd
廣義路徑問題
傳遞閉包
極小極大距離/極大極小距離
EulerPath/Tour
圈套圈演算法
混合圖的EulerPath/Tour
HamiltonPath/Tour
特殊圖的HamiltonPath/Tour構造
生成樹問題
最小生成樹
第k小生成樹
最優比率生成樹
0/1分數規劃
度限制生成樹
連通性問題
強大的DFS演算法
無向圖連通性
割點
割邊
二連通分支
有向圖連通性
強連通分支
2-SAT
最小點基
有向無環圖
拓撲排序
有向無環圖與動態規劃的關系
二分圖匹配問題
一般圖問題與二分圖問題的轉換思路
最大匹配(OK)
有向圖的最小路徑覆蓋
0/1矩陣的最小覆蓋
完備匹配(OK)
最優匹配(OK)
穩定婚姻
網路流問題
網路流模型的簡單特徵和與線性規劃的關系
最大流最小割定理
最大流問題(OK)
有上下界的最大流問題
循環流
最小費用最大流/最大費用最大流
弦圖的性質和判定
組合數學
解決組合數學問題時常用的思想
逼近
遞推/動態規劃
概率問題
Polya定理
計算幾何/解析幾何
計算幾何的核心:叉積/面積
解析幾何的主力:復數
基本形
點
直線,線段
多邊形
凸多邊形/凸包
凸包演算法的引進,卷包裹法
Graham掃描法
水平序的引進,共線凸包的補丁
完美凸包演算法
相關判定
兩直線相交
兩線段相交
點在任意多邊形內的判定
點在凸多邊形內的判定
經典問題
最小外接圓
近似O(n)的最小外接圓演算法
點集直徑
旋轉卡殼,對踵點
多邊形的三角剖分
數學/數論
高精度計算
高數度加減法、乘除法
最大公約數
Euclid演算法
擴展的Euclid演算法
同餘方程/二元一次不定方程
同餘方程組
線性方程組
高斯消元法
解mod2域上的線性方程組
整系數方程組的精確解法
矩陣
行列式的計算
利用矩陣乘法快速計算遞推關系
分數
分數樹
連分數逼近
數論計算
求N的約數個數
求phi(N)
求約數和
快速數論變換
……
素數問題
概率判素演算法
概率因子分解
數據結構
組織結構
二叉堆
左偏樹
二項樹
勝者樹
跳躍表
樣式圖標
斜堆
reap
統計結構
樹狀數組
虛二叉樹
線段樹
矩形面積並
圓形面積並
關系結構
Hash表
並查集
路徑壓縮思想的應用
STL中的數據結構
vector
deque
set/map
動態規劃/記憶化搜索
動態規劃和記憶化搜索在思考方式上的區別
最長子序列系列問題
最長不下降子序列
最長公共子序列
一類NP問題的動態規劃解法
樹型動態規劃
背包問題
動態規劃的優化
四邊形不等式
函數的凸凹性
狀態設計
規劃方向
線性規劃
常用思想
二分
最小表示法
串
KMP
Trie結構
後綴樹/後綴數組
LCA/RMQ
有限狀態自動機理論
排序
選擇/冒泡
快速排序
堆排序
歸並排序(OK)
基數排序
拓撲排序
排序網路
⑸ 怎樣求大組合數(取模)(ACM演算法)
這種題目然做過的,
意思比較簡單,就由 m 個共 0 和 n 個 1 組成一個串,但從左到右要1出現的次數不少於0出現的次數。
由大牛的演算法: 結果就是 C(m+n, n) - C(m+n, m-1) 再取模,我們可以對式子化簡一下就是:
(n+m)!*
(n-m+1) / ((m)!* (n+1)!)
再取模,但由於組合數很大,直接用大數乘除就會超時了,看了別人的報告才知道原來可以用素數化簡快速求模的, n! = 2^p[i] *
3^p[i] * 5^p[i]*...... 再求模就可以很快了~(^ = ^)~。。。
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
#define M 2000005
#define mm 20100501
bool sig[M];
int prime[150000], p[150000], len; // prime 記錄素數, p 記錄素數的冪 len 記錄長度
void getprime() // 篩法找素數
{
int i,j,k=0;
prime[k++] = 2;
for(i=3; i<=M; i+=2)
{
if( !sig[i] )
{
prime[k++] = i;
for(j=i; j<=M; j+=i)
sig[j] = 1;
}
}
}
void get(int k, int s) // K! 的素數分解, S為指數的加減(分母,分子)
{
int i, mid;
for(i=0; prime[i]<=k && prime[i]; i++)
{
mid = k;
while(mid)
{
if(s)
p[i] += mid/prime[i];
else
p[i] -= mid/prime[i];
mid /= prime[i];
}
}
if(len < i)
len = i;
}
__int64 cal() // 計算結果 (prime[i...]^p[i...]) % mm
{
__int64 i,ans = 1;
for(i=0; i<=len; i++)
{
if( p[i] )
{
__int64 t = prime[i], b = p[i], ret = 1;
while(b) //計算 (t^b) % mm
{
if(b%2) ret *= t %mm;
t = t*t%mm;
b /= 2;
}
ans = ( ans*ret ) % mm;
}
}
return ans;
}
int main()
{
int t,m,n,i,mid;
__int64 ans;
getprime();
cin>>t;
while(t--)
{
cin>>n>>m;
len = 0;
memset(p, 0, sizeof(p));
mid = n-m+1; //先前要把 n-m+1 的因子加進 P 中去才能使 (m+n)! / ((m)!*(n+1)!) 整除
for(i=0; mid>1; i++)
{
if( mid%prime[i] == 0)
{
while(mid%prime[i]==0)
{
p[i] += 1;
mid /= prime[i];
}
}
}
get(m+n, 1);
get(m, 0);
get(n+1, 0);
ans = cal();
printf("%I64d\n", ans);
}
return 0;
}
可以用素數分解法,
先求出上面和下面的素數表示,然後約分後,再用求冪公式
⑹ ACM初學者要學習的內容
ACM國際大學生程序設計競賽:知識與入門.pdf
鏈接: https://pan..com/s/19OY2FJUkk4RhW5WTsPkwfQ
《ACM國際大學生程序設計競賽:知識與入門》適用於參加ACM國際大學生程序設計競賽的本科生和研究生,對參加青少年信息學奧林匹克競賽的中學生也很有指導價值。
⑺ ACM 凸包 演算法
先解釋下凸包 顧名思義 就是多邊形是凸的 沒有某個點是凹進多邊形內部的 哈 文字我也描述不清楚 在高等數學里就有凸的定義 二次導數恆不小於0
再者 就是凸包演算法的定義了 凸包演算法一般就是計算能包裹住一個點集的最小的凸多邊形
至於具體的演算法 有很多 也不貼過來了 請看這篇帖子 偽代碼比較容易看懂演算法的原理
http://www.blogjava.net/sishuiweilan/archive/2007/10/10/151671.html
不懂的地方請追問
⑻ acm求個不超時的演算法思路
第一步:將輸入的數組進行排序,規則是由絕對值的大小由大到小排序 a[n] //用於存放輸入的數字 for(int i=0; i<n; i++) { for(int j=i; j<n; j++) if((a[i]>a[j] && a[i]>-a[j]) || (-a[i]>a[j] && -a[i]>-a[j]) ) { swap(a[i], a[j]); //數值互換函數 } } 排列好以後取出前m個數進行乘法運算,結果為result 然後判斷result是否大於零 如果大於零 你可以直接輸出了 如果小於零 找出數組前m個中最小的正數 min1 以及絕對值最小的負數 min2 以及後面的數中的最大的正數 max1 以及後面的數種絕對值最大的負數 max2 我們之前已經排列過了 應該很好找 進行判斷 if(min1*max1 > min2*max2) result = result/min2 *max1; else result = result/min1 *max2; 然後輸出結果result就成了 如果你還想輸出排列後的數組的話,就把前面判斷里的直接計算 改成剔除數字里的min2和max1 互換位置 或將 min1和max2 互換位置,再進行計算輸出就成了
⑼ 關於ACM競賽
ACM考的是演算法設計,編程,理解能力.
基本上ACM的題目都是英文的,所以你的英文要到火候,這個lz
應該沒問題吧.
還有最主要的就是演算法了,你可以去肯"演算法導論"這本牛書.
第三就是編程能力,ACM競賽中,時間也是一項衡量指標,怎樣在最快的時間內解決問題,編譯通過,並且運行正確.
最後,我覺得考慮問題的全面性也是很重要的,ACM的題目,很多都會有臨界情況,如何讓你的程序能夠通過這些臨界值的檢驗,很考察一個人思考問題的全面性的.