染色时间
题意

思路
优先队列广搜
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| #include <iostream> #include <cstring> #include <algorithm> #include <deque> #include <map> #include <vector> #include <time.h> #include <queue>
using namespace std; typedef pair<int,int> PII; typedef long long LL; const int N=100000,MOD=1e9+7,INF=0x3f3f3f3f;
int mp[510][510]; int f[510][510]; bool st[510][510]; int dx[4]={0,1,0,-1}; int dy[4]={1,0,-1,0}; int n,m; int ans=0;
priority_queue<pair<int,PII>> qu;
int main() { cin>>n>>m; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ cin>>mp[i][j]; f[i][j]=INF; } }
qu.push({-mp[1][1],{1,1}}); f[1][1]=mp[1][1]; st[1][1]=true; while(!qu.empty()){ auto tp=qu.top(); qu.pop(); int tt=-tp.first,x=tp.second.first,y=tp.second.second; for(int i=0;i<4;i++){ int nx=x+dx[i],ny=y+dy[i]; if(nx>n||ny>m||nx<1||ny<1||st[nx][ny]) continue; f[nx][ny]=tt+mp[nx][ny]; st[nx][ny]=true; qu.push({-f[nx][ny],{nx,ny}}); } }
for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ ans=max(ans,f[i][j]); } } cout<<ans<<endl;
return 0; }
|
总结
先用bfs 会TLE,下面介绍计算程序运行时间的方法
1 2 3 4 5 6
| clock_t startTime,endTime; startTime = clock();
endTime = clock(); cout << "The run time is: " <<(double)(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl;
|
k 倍区间
题意

思路
满足条件的两个数s[i]、s[j],当且仅当s[i]%k==s[j]%k && s[i]>=s[j]
计算前缀和%k后的结果,用map离散化。
对每个%k后的值,开一个数组,按顺序存储前缀和的原始值,这个数组的逆序对就是对答案的贡献。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| #include <iostream> #include <cstring> #include <algorithm> #include <deque> #include <map> #include <vector> using namespace std; typedef pair<int,int> PII; typedef long long LL;
int n,k; LL a[100010]; LL s[100010]; map<LL,LL> mp; LL ans,cnt,check; vector<LL> li[100010];
void merg(vector<LL> &list,int l,int r){ if(l>=r) return ; int mid=(l+r)>>1; merg(list,l,mid); merg(list,mid+1,r); int i=l,j=mid+1,kk=0; LL temp[r-l+1];
while(i<=mid&&j<=r){ if(list[i]>list[j]) temp[kk++]=list[i++]; else{ temp[kk++]=list[j++]; check+=mid-i+1; } } while(j<=r) temp[kk++]=list[j++]; while(i<=mid){ temp[kk++]=list[i++]; }
for(int ii=l,jj=0;ii<=r;ii++,jj++){ list[ii]=temp[jj]; } } int main() { cin>>n>>k; for(int i=1;i<=n;i++) cin>>a[i],s[i]=s[i-1]+a[i],cout<<s[i]<<" "; cout<<endl; for(int i=0;i<=n;i++){ LL temp = (s[i]%k+k)%k; if(mp[temp]!=0){ li[mp[temp]].push_back(s[i]); }else{ mp[temp]=++cnt; li[cnt].push_back(s[i]); } } for(int i=1;i<=cnt;i++){
check=0; merg(li[i],0,li[i].size()-1); ans+=check; } cout<<ans<<endl; return 0; }
|
总结
用归并排序求逆序对