数长方形
暴力
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=50;
int N;
struct node
{
int x1,y1,x2,y2;
} a[maxn];
int main()
{
int T,cas=1;
scanf("%d",&T);
while(T--)
{
scanf("%d",&N);
for(int i=0; i<N; i++)
{
scanf("%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2);
if(a[i].y1==a[i].y2&&a[i].x1>a[i].x2) swap(a[i].x1,a[i].x2);
if(a[i].x1==a[i].x2&&a[i].y1>a[i].y2) swap(a[i].y1,a[i].y2);
}
int ans=0;
for(int i=0; i<N; i++) if(a[i].x1==a[i].x2)
for(int j=i+1; j<N; j++) if(a[j].x1==a[j].x2)
for(int p=0; p<N; p++) if(a[p].y1==a[p].y2)
for(int q=p+1; q<N; q++) if(a[q].y1==a[q].y2)
if(a[i].x1!=a[j].x1&&a[p].y1!=a[q].y1)
if(a[p].y1>=max(a[i].y1,a[j].y1)&&a[p].y1<=min(a[i].y2,a[j].y2))
if(a[q].y1>=max(a[i].y1,a[j].y1)&&a[q].y1<=min(a[i].y2,a[j].y2))
if(a[i].x1>=max(a[p].x1,a[q].x1)&&a[i].x1<=min(a[p].x2,a[q].x2))
if(a[j].x1>=max(a[p].x1,a[q].x1)&&a[j].x1<=min(a[p].x2,a[q].x2)) ans++;
printf("Case #%d:\n%d\n",cas++,ans);
}
return 0;
}
弹吉他
Accepts: 495
Submissions: 1103
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
思路:暴力枚举手指品的状态
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int t,n,ans,pe[4]={0,1,2,3},stat[25][4],dp[5010][24];
struct node
{
int x,y;
bool operator < (const node& rhs) const
{
if(x==rhs.x) return y<rhs.y;
return x<rhs.x;
}
};
struct node1
{
node p[4];
}m[5010];
bool check(int i,int k)
{
int pos[4];
for(int l=0;l<4;l++)
{
int l1;
for(l1=0;l1<4;l1++)
if(stat[k][l1]==l)
pos[l]=m[i].p[l1].y;
}
if(pos[0]<=pos[1]&&pos[1]<=pos[2]&&pos[2]<=pos[3]) return true;
return false;
}
int cal(int i,int j,int k)
{
int ret=0;
for(int l=0;l<4;l++)
{
int l1,l2;
for(l1=0;l1<4;l1++)
if(stat[j][l1]==l)break;
for(l2=0;l2<4;l2++)
if(stat[k][l2]==l)break;
ret+=abs(m[i].p[l1].x-m[i+1].p[l2].x)+abs(m[i].p[l1].y-m[i+1].p[l2].y);
}
return ret;
}
int main()
{
scanf("%d",&t);
for(int i=0;i<24;i++)
{
for(int j=0;j<4;j++)
stat[i][j]=pe[j];
next_permutation(pe,pe+4);
}
for(int cas=1;cas<=t;cas++)
{
ans=INF;
scanf("%d",&n);
memset(m,0,sizeof(m));
memset(dp,INF,sizeof(dp));
dp[0][0]=0;
m[0].p[0].y=1;
m[0].p[1].y=2;
m[0].p[2].y=3;
m[0].p[3].y=4;
for(int i=1;i<=n;i++)
{
for(int j=0;j<4;j++)
scanf("%d%d",&m[i].p[j].x,&m[i].p[j].y);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<24;j++)
{
if(dp[i][j]==INF) continue;
for(int k=0;k<24;k++)
{
if(!check(i+1,k)) continue;
int gg=cal(i,j,k);
dp[i+1][k]=min(dp[i+1][k],dp[i][j]+gg);
}
}
}
for(int i=0;i<24;i++)
ans=min(ans,dp[n][i]);
printf("Case #%d:\n%d\n",cas,ans);
}
return 0;
}
行路难
思路:可以用bellman-floyed或者暴力。bellman的时候要注意从终点到起点开始,这样才能保证字典序最少
bellman是从bc上站过来的
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <climits>
#include <deque>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <algorithm>
#include <bitset>
#include <complex>
#include <string>
#include <utility>
using namespace std;
typedef long long LL;
typedef pair<int, int> Pii;
typedef pair<LL, LL> Pll;
#define foreach(it,s) for(__typeof(s.begin()) it=s.begin();it!=s.end();it++)
const int maxn = 50 + 5;
const int maxe = 500 + 5;
int n, m, s, t;
struct Tedge {
int u, v;
string w;
Tedge(int u = 0, int v = 0, string w = ""):u(u), v(v), w(w){};
};
vector<Tedge> edge[maxn];
string dis[maxn];
bool vis[maxn];
string bf()
{
int clk = 0;
memset(vis, false, sizeof(vis));
dis[t] = ""; vis[t] = true;
while (1) {
bool update = false;
for (int ii=0;ii<n;ii++) {
foreach(i, edge[ii])
if (vis[i->v]) {
int u = i->u, v = i->v;
string tmp = i->w + dis[v];
if (!vis[u] || tmp < dis[u]) {
dis[u] = tmp;
update = vis[u] = true;
if (clk >= n - 1 && u == s) return "Tough way!";
}
}
}
if (!update || ++clk > n * 6) break;
}
return vis[s] ? dis[s]: "Tough way!";
}
int main()
{
int cas = 0;
int T;
scanf("%d", &T);
while (T--) {
scanf("%d%d%d%d", &n, &m, &s, &t);
for (int i=0;i<n;i++) edge[i].clear();
printf("Case #%d:\n", ++cas);
for (int i=0;i<m;i++) {
int u, v;
char st[8];
scanf("%d%d%s", &u, &v, st);
edge[u].push_back(Tedge(u, v, st));
}
puts(bf().c_str());
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int maxn=100;
int G[maxn][maxn];
int N,M,A,B;
set<pair<string,int>, less<pair<string,int> > > q;
vector<pair<string,int> > edge[maxn];
void add_edge(int u,int v,string s)
{
edge[u].push_back(make_pair(s,v));
}
int main()
{
int T,cas=1,u,v;
string s;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d",&N,&M,&A,&B);
memset(G,0,sizeof(G));
for(int i=0;i<N;i++)
G[i][i]=1,edge[i].clear();
for(int i=1;i<=M;i++)
{
scanf("%d%d",&u,&v);
cin>>s;
add_edge(u,v,s);
G[u][v]=1;
}
for(int k=0;k<N;k++)
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
if(G[i][k]&&G[k][j])G[i][j]=1;
q.clear();
q.insert(make_pair("",A));
string tmp;
while(A!=B)
{
if(q.empty())break;
tmp=q.begin()->first;
A=q.begin()->second;
q.erase(q.begin());
if(tmp.length()>N*6)break;
for(int i=0;i<edge[A].size();i++)
{
int v=edge[A][i].second;
if(!G[v][B])continue;
string tmp1=tmp+edge[A][i].first;
q.insert(make_pair(tmp1,v));
}
}
printf("Case #%d:\n",cas++);
if(A==B)cout<<tmp<<endl;
else cout<<"Tough way!"<<endl;
}
return 0;
}
蜀道难
Accepts: 263
Submissions: 1306
Time Limit: 6000/3000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
线段树:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=200010;
int N;
int maxvid,maxvsum;
LL R;
int height[maxn];
struct IntervalTree
{
LL sum[maxn<<2];
int id[maxn<<2];
void build(int o,int l,int r)
{
if(l==r)
{
sum[o]=R*(l-1)+height[l];
id[o]=l;
return ;
}
int mid=(l+r)>>1;
build(o<<1,l,mid);
build(o<<1|1,mid+1,r);
pushup(o);
}
void pushup(int o)
{
if(sum[o<<1]<sum[o<<1|1])
{
sum[o]=sum[o<<1|1];
id[o]=id[o<<1|1];
}
else
{
sum[o]=sum[o<<1];
id[o]=id[o<<1];
}
}
void query(int o,int l,int r,int q1,int q2)
{
if(q1<=l&&r<=q2)
{
if(sum[o]>maxvsum)
{
maxvsum=sum[o];
maxvid=id[o];
}
return ;
}
int mid=(l+r)>>1;
if(q1<=mid)query(o<<1,l,mid,q1,q2);
if(q2>mid)query(o<<1|1,mid+1,r,q1,q2);
}
}tree;
int main()
{
int T,cas=1;
scanf("%d",&T);
while(T--)
{
scanf("%d%I64d",&N,&R);
for(int i=1;i<=N;i++)
scanf("%d",&height[i]);
for(int i=1;i<=N;i++)
height[i+N]=height[i];
tree.build(1,1,N*2);
LL anssum=0;
int x,y,p;
pair<int,int> ans=make_pair(N,N),tmp;
for(int i=1;i<=N*2;i++)
{
int r=i+N/2,l=i-N/2;
if(r>N*2||l<1)continue;
maxvid=maxvsum=0;
tree.query(1,1,N*2,i+1,r);
x=maxvid;
maxvid=maxvsum=0;
tree.query(1,1,N*2,l,i-1);
y=maxvid;
if((i-y)*R+height[i]+height[y]>anssum)
{
anssum=(i-y)*R+height[i]+height[y];
if(y>N)y-=N;
p=i;
if(p>N)p-=N;
tmp=make_pair(min(y,p),max(y,p));
ans=tmp;
}
else if((i-y)*R+height[i]+height[y]==anssum)
{
if(y>N)y-=N;
p=i;
if(p>N)p-=N;
tmp=make_pair(min(y,p),max(y,p));
if(tmp<ans)ans=tmp;
}
if((x-i)*R+height[x]+height[i]>anssum)
{
anssum=(x-i)*R+height[x]+height[i];
if(x>N)x-=N;
p=i;
if(p>N)p-=N;
tmp=make_pair(min(x,p),max(x,p));
ans=tmp;
}
else if((x-i)*R+height[x]+height[i]==anssum)
{
if(x>N)x-=N;
p=i;
if(p>N)p-=N;
tmp=make_pair(min(x,p),max(x,p));
if(tmp<ans)ans=tmp;
}
}
printf("Case #%d:\n",cas++);
printf("%d %d\n",ans.first,ans.second);
}
return 0;
}
单调队列:
#include<bits/stdc++.h>
using namespace std;
const int maxn=200010;
typedef long long LL;
int height[maxn];
int N,q[maxn];
LL qh[maxn];
LL R;
int main()
{
int T,cas=1;
scanf("%d",&T);
while(T--)
{
scanf("%d%I64d",&N,&R);
for(int i=1;i<=N;i++)
{
scanf("%d",&height[i]);
height[i+N]=height[i];
}
int ansx=0,ansy=0;
LL ans=0;
int s=1,t=0;
for(int i=1;i<=2*N;i++)
{
while(s<=t&&(i-q[s])*2>N)s++;
if(s<=t)
{
if(ans<height[i]+R*i+qh[s])
{
ans=height[i]+R*i+qh[s];
ansx=q[s]>N?q[s]-N:q[s];
ansy=i>N?i-N:i;
if(ansx>ansy)swap(ansx,ansy);
}
else if(ans==height[i]+R*i+qh[s])
{
int x=q[s]>N?q[s]-N:q[s];
int y=i>N?i-N:i;
if(x>y)swap(x,y);
if(ansx>x||ansx==x&&ansy>y)ansx=x,ansy=y;
}
}
while(s<=t&&height[i]-R*i>qh[t])t--;
t++;
q[t]=i;
qh[t]=height[i]-R*i;
}
printf("Case #%d:\n",cas++);
printf("%d %d\n",ansx,ansy);
}
return 0;
}
最强密码
Accepts: 253
Submissions: 590
Time Limit: 10000/5000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
using namespace std;
typedef long long LL;
const int maxn=100010;
const int MOD=1e9+7;
char str[maxn];
int dp[maxn];
int pos[30];
int nxt[maxn][30];
LL cnt[maxn];
int main()
{
int T,cas=1;
scanf("%d",&T);
while(T--)
{
scanf("%s",str);
int N=strlen(str);
for(int i=0;i<26;i++)pos[i]=N+1;
for(int i=N-1;i>=0;i--)
{
pos[str[i]-'a']=i+1;
for(int j=0;j<26;j++)
nxt[i][j]=pos[j];
}
dp[N+1]=0,dp[N]=1;
for(int i=N-1;i>=0;i--)
{
int minv=N+1;
for(int j=0;j<26;j++)
minv=min(minv,dp[nxt[i][j]]+1);
dp[i]=minv;
}
memset(cnt,0,sizeof(cnt));
cnt[N]=26,cnt[N+1]=1;
for(int i=N-1;i>=0;i--)
{
for(int j=0;j<26;j++)
if(dp[i]==dp[nxt[i][j]]+1)
{
cnt[i]+=cnt[nxt[i][j]];
if(cnt[i]>=MOD)cnt[i]-=MOD;
}
}
printf("Case #%d:\n%d %I64d\n",cas++,dp[0],cnt[0]);
}
return 0;
}