POJ - 3617
题意: 从原串的头和尾部取字符,加到新串的尾部。让新 串的字典序最小,每80个字符换一次行。
思路: 要使字典序最小每个位置都取头和尾最小的那个加到新串的尾部,相等时则看头和尾谁能够将以后较小的字符更早的加入新串的尾部。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MN=2010;
char c[MN];
int main()
{
int n;
scanf("%d",&n);
for(int i=0; i<n; i++)
{
getchar();
scanf("%c",&c[i]);
}
int he=0,ta=n-1,sum=0;
while(he<=ta)
{
sum++;
if(c[he]<c[ta])
{
printf("%c",c[he]);
he++;
}
else if(c[he]>c[ta])
{
printf("%c",c[ta]);
ta--;
}
else
{
int i=he,j=ta;
while(i<j && c[i]==c[j]) i++,j--;
if(c[i]<=c[j])
{
printf("%c",c[he]);
he++;
}
else
{
printf("%c",c[ta]);
ta--;
}
}
if(sum%80==0) printf("\n");
}
return 0;
}
POJ - 3253
题意: 将一整块木板切成N块长度各是Li的木板,切割一次的花费等于木板的长度,求最小总花费。
思路: 霍夫曼编码,用优先队列模拟。
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
int main()
{
int n,t;
priority_queue<int,vector<int>,greater<int> >Q;
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&t);
Q.push(t);
}
ll ans=0;
while(Q.size()>1)
{
int d1=Q.top();
Q.pop();
int d2=Q.top();
Q.pop();
ans+=d1+d2;
Q.push(d1+d2);
}
printf("%lld\n",ans);
return 0;
}
POJ - 2689
题意: 给出区间 [L,R],求这个区间最相距最小,最大的素数对。
思路: 2到 sqrt N 内的素数 能把小于N的非素数全部标记,剩下的就是素数。先将10的6次方以内的素数打表,然后用这些素数将从L到R的非素数标记。
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MN=1000010;
int g,p[MN];
bool vis[MN],bk[MN];
void prime()
{
for(int i=2; i<MN; i++)
{
if(!vis[i]) p[++g]=i;
for(int j=1; j<=g && i*p[j]<MN; j++)
{
vis[i*p[j]]=1;
if(i%p[j]==0) break;
}
}
}
int main()
{
prime();
ll L,R;
while(~scanf("%lld %lld",&L,&R))
{
memset(bk,0,sizeof(bk));
if(L==1) bk[0]=1;
for(int i=1; p[i]*p[i]<=R && i<=g; i++)
{
ll he;
if(L%p[i]) he=(L/p[i]+1)*p[i];
else he=L;
if(he==p[i]) he+=p[i];
for(ll j=he; j<=R; j+=p[i])
bk[j-L]=1;
}
ll last=-1,mi=R,ma=0,mil,mir,mal,mar;
for(ll i=L; i<=R; i++)
{
if(!bk[i-L])
{
if(last!=-1 && ma<i-last)
{
ma=i-last;
mal=last;
mar=i;
}
if(last!=-1 && mi>i-last)
{
mi=i-last;
mil=last;
mir=i;
}
last=i;
}
}
if(mi==R) printf("There are no adjacent primes.\n");
else printf("%lld,%lld are closest, %lld,%lld are most distant.\n",mil,mir,mal,mar);
}
return 0;
}
POJ - 1144
题目: 给出无向图,求割点的个数,模板题。
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MN=110;
int g,fir[MN],nex[MN*MN],to[MN*MN];
void add(int x,int y)
{
++g;
to[g]=y,nex[g]=fir[x],fir[x]=g;
}
int root,vis[MN];
int sum,num,dfn[MN],low[MN];
void tarjan(int u)
{
int sbt=0;
dfn[u]=low[u]=++num;
for(int i=fir[u]; i; i=nex[i])
{
int du=to[i];
if(!dfn[du])
{
sbt++;
tarjan(du);
low[u]=min(low[u],low[du]);
if( (u==root && sbt>1 ) || (u!=root && dfn[u]<=low[du]) )
{
if(!vis[u])
{
vis[u]=1;
sum++;
}
}
}
else low[u]=min(low[u],dfn[du]);
}
}
int main()
{
int n;
while(~scanf("%d",&n)&&n)
{
g=sum=num=0;
memset(fir,0,sizeof(fir));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(vis,0,sizeof(vis));
int t1,t2;
while(~scanf("%d",&t1)&&t1)
{
char ch;
while((ch=getchar())!='\n')
{
scanf("%d",&t2);
add(t1,t2),add(t2,t1);
}
}
// root=1;
// tarjan(1);
for(int i=1; i<=n; i++)
{
if(!dfn[i])
{
root=i;
tarjan(i);
}
}
printf("%d\n",sum);
}
return 0;
}
HYSBZ - 1607
题意: 对于每头牛,求其他牛的纸条上数字是它的纸条上数因子的个数。
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MN=1000010;
int a[MN],num[MN],cnt[MN];
int main()
{
int N;
while(~scanf("%d",&N))
{
memset(cnt,0,sizeof(num));
memset(cnt,0,sizeof(cnt));
for(int i=0; i<N; i++)
{
scanf("%d",&a[i]);
num[a[i]]++;
}
for(int i=2; i<MN; i++)
{
if(num[i]==0) continue;
for(int j=i; j<MN; j+=i)
cnt[j]+=num[i];
}
for(int i=0; i<N; i++)
printf("%d\n",cnt[a[i]]-1+num[1]);
}
return 0;
}
计蒜客 - T2013
快速幂模板
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
ll fpow(ll a,ll b,ll MD)
{
ll ans=1,base=a;
while(b)
{
if(b&1) ans=(ans*base)%MD;
base=(base*base)%MD;
b>>=1;
}
return ans;
}
int main()
{
ll n,m,k,x;
scanf("%lld %lld %lld %lld",&n,&m,&k,&x);
printf("%lld\n",(m*fpow(10,k,n)%n+x)%n);
return 0;
}