​​1101: 报数游戏​​

#include<cstdio>
int solve(int x)
{
if(x%7==0) return 1;
int a,flag=0;
while(x>1)
{
a=x%10;
if(a==7) {flag=1;break;}
x/=10;
}
if(flag) return 1;
return 0;
}
int main()
{
int n,m,k,a,b,y,c;
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
if(n==0&&m==0&&k==0) break;
a=m;
if(solve(a))
{
if(k==1) {printf("%d\n",a);continue; }
else k--;
}
while(k>=1)
{
c=a;
a=a+(n-m)*2;
if(a!=c&&solve(a))
{
if(k==1) {y=a; break;}
else k--;
}
//printf("%d\n",a);
c=a;
a=a+(m-1)*2;
//printf("%d\n",a);
if(a!=c&&solve(a))
{
if(k==1) {y=a;break;}
else k--;
}
}
printf("%d\n",y);
}
return 0;
}

​​1102: 多连块拼图​​

#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;

int n,m;
char s1[20][20]; //目标字符串
char s2[20][20]; //匹配字符串
int a,b;
int c,d;

void get_big()
{
int flag=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(s1[i][j]=='*')
{
a=i;
b=j;
flag=1;
break;
}
}
if(flag)break;
}
}

void get_small()
{
int flag=0;
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
if(s2[i][j]=='*')
{
c=i;
d=j;
flag=1;
break;
}
}
if(flag)break;
}
}

bool check()
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(s1[i][j]=='*')return false;
}
return true;
}

int solve()
{
get_small();
while(!check())
{
get_big();
for(int i=c;i<m;i++)
for(int j=0;j<m;j++)
{
if(s2[i][j]=='*') //开始匹配
{
if(s1[i-c+a][j-d+b]=='*')
{
s1[i-c+a][j-d+b]='.';
}
else
return 0;
}
}
}
return 1;
}

int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0 && m==0)break;
for(int i=0;i<n;i++)scanf("%s",s1[i]);
for(int i=0;i<m;i++)scanf("%s",s2[i]);
int ans=solve();
cout<<ans<<endl;
}
return 0;
}

​​1105: 打怪升级​​

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn = 1005;
const int inf = 0x3f3f3f3f;
int n,p;
int t1[maxn],t2[maxn];
int p1[maxn],p2[maxn];
int w1[maxn],w2[maxn];
double dp[maxn][105][15];

int main()
{
while(scanf("%d %d",&n,&p),n+p)
{
for(int i = 1; i <= n; i++)
scanf("%d %d %d %d %d %d",&p1[i],&p2[i],&t1[i],&t2[i],&w1[i],&w2[i]);
for(int i = 0; i <= n; i++)
for(int j = 0; j <= 101; j++)
for(int k = 0; k <= 10; k++)
dp[i][j][k] = inf;
dp[0][p][0] = 0;
for(int i = 1; i <= n; i++)
for(int j = 0; j <= 101; j++)
for(int k = 0; k <= 10; k++)
{
if(dp[i-1][j][k] == inf) continue;
if(j < p1[i]) continue;
double T;
if(j > p2[i]) T = t2[i];
else if(j <= p2[i] && j >= p1[i]) T = t1[i] - ((j - p1[i]) * 1.0 / (p2[i] - p1[i])) * (t1[i] - t2[i] + 0.0);
int tmp = j + w1[i]; //获得的w1
int tmp2 = k + w2[i];
if(tmp > 101) tmp = 101;
if(tmp2 > 10) tmp2 = 10;
dp[i][tmp][tmp2] = min(dp[i][tmp][tmp2],dp[i-1][j][k] + T);
int tmp3 = tmp;
for(int q = 1; q <= tmp2; q++) //喝药
{
tmp3 = tmp3 * 2;
if(tmp3 > 101)
dp[i][101][tmp2 - q] = min(dp[i][101][tmp2-q],dp[i][tmp][tmp2]);
else dp[i][tmp3][tmp2 - q] = min(dp[i][tmp3][tmp2-q],dp[i][tmp][tmp2]);
}
}
double ans = inf;
for(int i = 0; i <= 101; i++)
for(int j = 0; j <= 10; j++)
ans = min(ans,dp[n][i][j]);
if(ans == inf) printf("Impossible\n");
else printf("%.2lf\n",ans);
}
return 0;
}

​​1106: 最优对称路径​​

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define mod 1000000009
#define maxn 205
#define INF 0x3f3f3f3f
using namespace std;
struct node
{
int x,y,s;
} head,t;
long long dp[maxn][maxn];
int dir[4][2]= {1,0,0,1,-1,0,0,-1};
int dis[maxn][maxn];
int vis[maxn][maxn];
int v[maxn][maxn];
int n,min_dis;

int ok(int x,int y)
{
if(x<1||y<1||x+y>n+1)
return 0;
return 1;
}

void spfa()
{
memset(dis,INF,sizeof(dis));
memset(vis,0,sizeof(vis));
int tx,ty;
min_dis=INF;
queue<node>q;
q.push((node){1,1});
dis[1][1]=v[1][1];
while(!q.empty())
{
head=q.front();
q.pop();
vis[head.x][head.y]=0;
if(head.x+head.y==n+1)
{
if(dis[head.x][head.y]<min_dis)
min_dis=dis[head.x][head.y];
continue;
}
for(int i=0; i<4; i++)
{
tx=head.x+dir[i][0];
ty=head.y+dir[i][1];
if(ok(tx,ty)&&dis[tx][ty]>dis[head.x][head.y]+v[tx][ty])
{
dis[tx][ty]=dis[head.x][head.y]+v[tx][ty];
if(!vis[tx][ty])
{
vis[tx][ty]=1;
q.push((node){tx,ty});
}
}
}
}
}

long long dfs(int x,int y) //记忆化搜索
{
if(dp[x][y]!=-1)
return dp[x][y];
if(x+y==n+1)
return dp[x][y]=dis[x][y]==min_dis;
dp[x][y]=0;
int tx,ty;
for(int i=0;i<4;i++)
{
tx=x+dir[i][0];
ty=y+dir[i][1];
if(ok(tx,ty)&&(dis[x][y]+v[tx][ty]==dis[tx][ty])) //满足最短的
dp[x][y]=(dp[x][y]+dfs(tx,ty))%mod;
}
return dp[x][y];
}

int main()
{
while(~scanf("%d",&n)&&n)
{
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
{
scanf("%d",&v[i][j]);
if(i+j>n+1)
v[n+1-j][n+1-i]+=v[i][j]; //对折
}
spfa();
memset(dp,-1,sizeof(dp));
printf("%lld\n",dfs(1,1));
}
return 0;
}

​​1107: Pieces and Discs​​

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<map>
using namespace std;
const int maxn = 41;
const int maxm = maxn * maxn;
const double eps = 1e-8;
const double pi = acos(-1.0);
int dcmp(double x)
{
if(x < -eps) return -1;
return x > eps;
}
struct Point
{
double x, y, r;
bool operator <(const Point &b)const
{
if(dcmp(x - b.x) == 0)
return y < b.y;
return x < b.x;
}
};
typedef struct
{
Point s, e;
double ang, d;
} Line;

inline double det(double x1, double y1, double x2, double y2)
{
return x1 * y2 - x2 * y1;
}
double cross(Point a, Point b, Point c)
{
return det(b.x - a.x, b.y - a.y, c.x - a.x, c.y - a.y);
}
Point MakePoint(double xx, double yy)
{
Point res;
res.x = xx, res.y = yy;
return res;
}


int n, m, L, W, pnum;
vector<Point> ap;
vector<int> lp[maxn], adjp[maxm];
vector<Line> l;
vector<double> ans[maxn];
map<Point, int> M;
Point c[maxn];
bool visp[maxm];

Line SetLine(Point a, Point b)
{
Line l;
l.s = a;
l.e = b;
l.ang = atan2(b.y - a.y, b.x - a.x);
if(dcmp(a.x - b.x)) l.d = (a.x * b.y - b.x * a.y) / fabs(a.x - b.x);
else l.d = (a.x * b.y - b.x * a.y) / fabs(a.y - b.y);
return l;
}
double dotdet(double x1, double y1, double x2, double y2)
{
return x1 * x2 + y1 * y2;
}
double dot(Point a, Point b, Point c)
{
return dotdet(b.x - a.x, b.y - a.y, c.x - a.x, c.y - a.y);
}
int betweenCmp(Point a, Point b, Point c)
{
return dcmp(dot(a, b, c));
}
bool segcross(Point a, Point b, Point c, Point d, Point &p)
{
double s1, s2, s3, s4;
int d1, d2, d3, d4;
d1 = dcmp(s1 = cross(a, b, c));
d2 = dcmp(s2 = cross(a, b, d));
d3 = dcmp(s3 = cross(c, d, a));
d4 = dcmp(s4 = cross(c, d, b));
if((d1 ^ d2) == -2 && (d3 ^ d4 == -2))
{
p.x = (c.x * s2 - d.x * s1) / (s2 - s1);
p.y = (c.y * s2 - d.y * s1) / (s2 - s1);
return true;
}
if(d1 == 0 && betweenCmp(c, a, b) <= 0)
{
p = c;
return true;
}
if(d2 == 0 && betweenCmp(d, a, b) <= 0)
{
p = d;
return true;
}
if(d3 == 0 && betweenCmp(a, c, d) <= 0)
{
p = a;
return true;
}
if(d4 == 0 && betweenCmp(b, c, d) <= 0)
{
p = b;
return true;
}
return false;
}

bool CrossPoint(const Line &la, const Line &lb, Point &p)
{
return segcross(la.s, la.e, lb.s, lb.e, p);
}
bool Parallel(const Line &la, const Line &lb)
{
return !dcmp( (la.e.x - la.s.x) * (lb.e.y - lb.s.y) -
(la.e.y - la.s.y) * (lb.e.x - lb.s.x) );
}
double PolygonArea(vector<int> p)
{
if(p.size() < 4) return 0.0;
double s = ap[p[0]].y * (ap[p[p.size() - 2]].x - ap[p[1]].x);
for(int i = 1; i < p.size() - 1; ++ i)
s += ap[p[i]].y * (ap[p[i - 1]].x - ap[p[i + 1]].x);
return fabs(s * 0.5);
}
inline double CalLen(double a, double b)
{
return sqrt(a * a + b * b);
}
inline double CalDis(Point a, Point b)
{
return CalLen(a.x - b.x, a.y - b.y);
}
inline bool InCir(Point a, Point b)
{
return dcmp(CalDis(a, b) - b.r) < 0;
}
inline bool OnCir(Point a, Point b)
{
return dcmp(CalDis(a, b) - b.r) == 0;
}
double DisPtoL(Point p, Point a, Point b)
{
return fabs(cross(p, a, b)) / CalDis(a, b);
}
bool EqualPoint(Point a, Point b)
{
return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}
bool SegIntersCircle(Point a, Point b, Point c)
{
Point t = c;
t.x += a.y - b.y;
t.y += b.x - a.x;
return cross(a, c, t) * cross(b, c, t) < eps &&
DisPtoL(c, a, b) - c.r < -eps;
}
bool JudgePiece(int i, vector<int> ps)
{
int j, k, cnt = 0;
for(j = 1; j < ps.size(); ++ j)
{
if(InCir(ap[ps[j]], c[i])) return true;
else if(OnCir(ap[ps[j]], c[i])) ++ cnt;
}
if(cnt >= 2) return true;
for(j = 1; j < ps.size(); ++ j)
for(k = j + 1; k < ps.size(); ++ k)
{
if(SegIntersCircle(ap[ps[j]], ap[ps[k]], c[i]))
return true;
}
for(j = 1; j < ps.size(); ++ j)
if(cross(ap[ps[j - 1]], ap[ps[j]], c[i]) < -eps) return false;
return true;
}
void FindPiece(int s0, int s1)
{
vector<int> ps;
int i, j, nex = s1, ori = s0;
double s;
ps.push_back(s0);
ps.push_back(s1);
while(nex != ori)
{
nex = -1;
for(i = 0; i < adjp[s1].size(); ++ i)
{
if(EqualPoint(ap[adjp[s1][i]], ap[s0])) continue;
if(cross(ap[s0], ap[s1], ap[adjp[s1][i]]) > -eps &&
(nex == -1 || cross(ap[s1], ap[nex], ap[adjp[s1][i]]) > eps))
nex = adjp[s1][i];
}
if(nex != -1 && (!visp[nex] || nex == ori))
ps.push_back(nex);
else return;
s0 = s1, s1 = nex;
}
s = PolygonArea(ps);
if(!dcmp(s)) return;
for(i = 0; i < m; ++ i)
if(JudgePiece(i, ps))
ans[i].push_back(s);
}

bool cmp(const int &a, const int &b)
{
if(dcmp(ap[a].x - ap[b].x) == 0)
return ap[a].y < ap[b].y;
return ap[a].x < ap[b].x;
}
int main()
{
int i, j, pnum;
double sx, sy, ex, ey;
while(scanf("%d%d%d%d", &n, &m , &L, &W), n | m | L | W)
{
l.clear();
n += 4;
M.clear();
ap.clear();
memset(visp, 0, sizeof(visp));
l.push_back(SetLine(MakePoint(0, 0), MakePoint(L, 0)));
l.push_back(SetLine(MakePoint(L, 0), MakePoint(L, W)));
l.push_back(SetLine(MakePoint(L, W), MakePoint(0, W)));
l.push_back(SetLine(MakePoint(0, W), MakePoint(0, 0)));
for(i = 4; i < n; ++ i)
{
scanf("%lf%lf%lf%lf", &sx, &sy, &ex, &ey);
l.push_back(SetLine(MakePoint(sx, sy), MakePoint(ex, ey)));
}
for(i = 0; i < m; ++ i)
scanf("%lf%lf%lf", &c[i].x, &c[i].y, &c[i].r), ans[i].clear();
for(i = 0; i < n; ++ i) lp[i].clear();
for(i = pnum = 0; i < n; ++ i)
for(j = i + 1; j < n; ++ j)
{
Point tmp;
if(CrossPoint(l[i], l[j], tmp))
{
if(!M.count(tmp))
adjp[pnum].clear(), M[tmp] = pnum ++, ap.push_back(tmp);
lp[i].push_back(M[tmp]);
lp[j].push_back(M[tmp]);
}
}
for(i = 0; i < n; ++ i)
{
sort(lp[i].begin(), lp[i].end(), cmp);
for(j = 1; j < lp[i].size(); ++ j)
{
if(!EqualPoint(ap[lp[i][j]], ap[lp[i][j - 1]]))
{
adjp[lp[i][j]].push_back(lp[i][j - 1]);
adjp[lp[i][j - 1]].push_back(lp[i][j]);
}
}
}
for(i = 0; i < pnum; ++ i)
{
if(!visp[i])
{
visp[i] = true;
for(j = 0; j < adjp[i].size(); ++ j)
if(!visp[adjp[i][j]])FindPiece(i, adjp[i][j]);
}
}
for(i = 0; i < m; ++ i)
{
sort(ans[i].begin(), ans[i].end());
printf("%d", ans[i].size());
for(j = 0; j < ans[i].size(); ++ j)
printf(" %.2f", ans[i][j]);
printf("\n");
}
printf("\n");
}
return 0;
}

​​1110: RMQ with Shifts​​

#include <stdio.h>  
#include <algorithm>
#include <iostream>
#include <string.h>
using namespace std;
#define lson l, m, rt << 1
#define rson m+1, r, rt << 1 | 1

const int maxn = 111111;
int minn[maxn<<2];

void pushup(int rt)
{
minn[rt] = min(minn[rt << 1], minn[rt << 1 | 1]);
}

void build(int l, int r, int rt)
{
if(l == r)
{
scanf("%d", &minn[rt]);
return;
}
int m = (l+r) >> 1;
build(lson);
build(rson);
pushup(rt);
}

int query(int L, int R, int l, int r, int rt)
{
if(L <= l && R >= r)
return minn[rt];
int m = (l+r) >> 1;
int res = 0x3f3f3f3f;
if(m >= L) res = min(res, query(L, R, lson));
if(m < R) res = min(res, query(L, R, rson));
return res;
}

void update(int l, int r, int rt, int loc, int val)
{
if(l == r)
{
minn[rt] = val;
return;
}
int m = (l+r) >> 1;
if(m >= loc) update(lson, loc, val);
else update(rson, loc, val);
pushup(rt);
}

int main()
{
int n, q, cnt;
char s[35];
int a[30];
scanf("%d%d", &n, &q);
build(1, n, 1);
while(q--)
{
scanf("%s", s);
if(s[0] == 'q')
{
int l = 0, r = 0, i;
for(i = 6; s[i] != ','; i++)
l = l*10 + s[i]-'0';
for(i++; s[i] != ')'; i++)
r = r*10 + s[i]-'0';
printf("%d\n", query(l, r, 1, n, 1));
}
else
{
cnt = 0;
int i = 6;
while(s[i] != ')' && s[i] != '\0')//把shift的数存到a数组
{
int num = 0;
while(s[i] != ',' && s[i] != ')')
{
num = num * 10 + s[i] - '0';
i++;
}
i++;
a[cnt++] = num;
}
int tmp = query(a[0], a[0], 1, n, 1);//这几行都是在循环移动
for(int i = 0; i < cnt-1; i++)
{
int c = (i+1)%cnt;
int rr = query(a[c], a[c], 1, n, 1);
update(1, n, 1, a[i], rr);
}
update(1, n, 1, a[cnt-1], tmp);
}
}
return 0;
}

​​1116: Kingdoms​​

#include <iostream>
#include <algorithm>
#include <iterator>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
#define INF 0x3f3f3f3f

int map[20][20],people[20],low[20];
int n,m,p;
int vis[20];

int prim(int t,int& sum)
{
memset(vis,0,sizeof(vis));

int pos,price,tot;
pos=1; price=0; tot=0;

for(int i=1;i<=n;i++)//寻找每种情况包含的点
{
vis[i]=t&1;
t=(t>>1);
if(vis[i]) tot++;//记录有多少点
}
if(vis[1]==0) tot++;

for(int i=1;i<=n;i++)
{
if(vis[i]) low[i]=map[pos][i];
else low[i]=INF;
}
low[1]=0; vis[1]=2; tot--;//只需要将tot个点进行最小生成树就行了

int MIN;
for(int k=1;k<=tot;k++)
{
MIN=INF; pos=1;
for(int i=1;i<=n;i++)
{
if(vis[i]==1&&MIN>low[i])
{
MIN=low[i]; pos=i;
}
}

if(pos==1) return INF;//如果存在点扩展不到,就果断放弃这种情况

price+=low[pos]; sum+=people[pos]; vis[pos]=2;

for(int i=1;i<=n;i++)
{
if(vis[i]==1&&map[pos][i]<low[i])
low[i]=map[pos][i];
}
}

return price;
}

int main()
{
// freopen("s","r",stdin);

int T;
scanf("%d",&T);

while(T--)
{
memset(map,0x3f,sizeof(map));

scanf("%d%d%d",&n,&m,&p);

for(int i=1;i<=n;i++)
scanf("%d",&people[i]);//记录每个城市的人数

for(int j=1;j<=m;j++)
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);

if(c<map[u][v])//处理重边,保留花费最少的边
{
map[u][v]=map[v][u]=c;
}
}

int price,sum,res=0;
// cout<<(1<<(n-1))<<endl;
for(int i=0;i<=(1<<(n));i++)//枚举点,对每个情况找一次最小生成树
{
sum=people[1];
price=prim(i,sum);//返回总花费
if(price<=p) res=max(res,sum);//更新最大的人数
}

printf("%d\n",res);
}
return 0;
}

​​1117: 网格中的三角形​​

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long ll;

inline ll max(ll a, ll b) {
return a > b ? a : b;
}

inline ll min(ll a, ll b) {
return a < b ? a : b;
}

ll N, M, A, B;

ll solve (ll k) {
if (k < 0)
k = 0;

if (N > M)
swap(N, M);

ll ans = 0;
for (ll n = 1; n <= N; n++) {
for (ll m = 1; m <= M; m++) {
ll cnt = 0;

if (n * m <= k)
cnt += 2 * (n + m - 2);

ll l, r;
for (ll x = 0; x <= n; x ++) {
r = (m * x + k) / n;

if (r > m)
r = m;

ll t = m * x - k;

if(t <= 0)
l = 0;
else
l = (t - 1) / n + 1;

if(l <= r)
cnt += 2 * (r - l + 1);
}

for (ll x = 1; x < n; x++) {
ll tmp = n * m - x;

if (tmp <= k)
cnt += 4 * (m - 1);
else {
tmp = tmp - k;
ll u = m-1 - min(tmp / x + (tmp % x != 0), m-1);
cnt += 4 * u;
}
}
//printf("%lld %lld %lld\n",n , m, cnt);
ans += cnt * (N - n + 1) * (M - m + 1);
}
}
return ans;
}

int main () {
int cas;
scanf("%d", &cas);
while (cas--) {
scanf("%lld%lld%lld%lld", &N, &M, &A, &B);
printf("%lld\n", solve(B*2) - solve(A*2-1));
}
return 0;
}

​​1119: Collecting Coins​​

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct node{
int x,y,flag;
};
node st[6];
node ccc[11];
int n,m;
int vis[30][30];
char map[30][30];
int zx,zy;
int cnt;
int res,ans,ans1;
int c,co;
int dir[4][2]={1,0,-1,0,0,1,0,-1};
int jude(int x,int y)
{
if(x<1||x>n||y<1||y>m) return 0;
return 1;
}
void dfs(int x,int y)
{
if(map[x][y]=='C') res++,map[x][y]='.';
vis[x][y]=1;
for(int i=0;i<4;i++)
{ int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(!jude(xx,yy)||vis[xx][yy]||map[xx][yy]=='O'||map[xx][yy]=='X') continue;
dfs(xx,yy);
}
}
void dfs4(int x,int y,node *df,int &co)//推完一个石头能吃到的金币个数
{
if(map[x][y]=='C') res++,map[x][y]='.',df[co].x=x,df[co++].y=y;//记录金币的位置,后面回溯。
vis[x][y]=1;
for(int i=0;i<4;i++)
{ int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(!jude(xx,yy)||vis[xx][yy]||map[xx][yy]=='O'||map[xx][yy]=='X') continue;
dfs4(xx,yy,df,co);

}
}
int dfs1(int x,int y,int zx,int zy)//判断是否能到达推石头的那个点。
{
vis[x][y]=1;
if(x==zx&&y==zy) return 1;
for(int i=0;i<4;i++)
{ int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(!jude(xx,yy)||vis[xx][yy]||map[xx][yy]=='X'||map[xx][yy]=='O') continue;
if(dfs1(xx,yy,zx,zy)) return 1;
}
return 0;
}
void solove(int num,int sum)//第几个石头,金币和
{
if(num==cnt-1)//最后一个石头推完
{
if(ans1<sum) ans1=sum;
return ;
}
if(ans+ans1==c) return ;
for(int i=1;i<cnt&&ans+ans1<c;i++)//暴力枚举石头
{
if(!st[i].flag) continue ;
st[i].flag=0;
for(int j=0;j<4;j++)//枚举方向
{
int xx=st[i].x+dir[j][0];//根据你的位置得到的石头的前后位置。
int yy=st[i].y+dir[j][1];
int x2=st[i].x-dir[j][0];
int y2=st[i].y-dir[j][1];
if(!jude(xx,yy)||map[xx][yy]=='C'||map[xx][yy]=='O'||map[xx][yy]=='X') continue;//当石头后面不为空或者出界
if(!jude(x2,y2)||map[x2][y2]=='O'||map[x2][y2]=='X') continue;//当人站的那个位置还有石头或者为障碍
memset(vis,0,sizeof(vis));
if(!dfs1(zx,zy,x2,y2)) continue;//当人不能到达推石头的那个位置
map[st[i].x][st[i].y]='.';//能推就把石头那个位置变成路
map[xx][yy]='X';//石头后面的位置变成障碍
memset(vis,0,sizeof(vis));
int co=0;
node *df=(node*)malloc(sizeof(node)*10);//最多是个金币,用来保存这一轮完石头所吃的金币位置用于后面的回溯
res=0;
dfs4(zx,zy,df,co);//推完这次石头然后去吃硬币
solove(num+1,sum+res);//继续往下面枚举石头
for(int k=0;k<co;k++)//回溯地图上的金币
{
map[df[k].x][df[k].y]='C';
}
map[st[i].x][st[i].y]='O';//回溯石头的位置
map[xx][yy]='.';

}
st[i].flag=1;
if(ans1<sum) ans1=sum;//取最大
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&m);
cnt=1;
c=0;
for(int i=1;i<=n;i++)
{
scanf("%s",map[i]+1);
for(int j=1;j<=m;j++)
{
if(map[i][j]=='S')
{
zx=i;
zy=j;
map[i][j]='.';

}
if (map[i][j] == 'C') c++;
if(map[i][j]=='O')
{
st[cnt].x=i,st[cnt].y=j;
st[cnt++].flag=1;
}
}
}
res=0;
memset(vis,0,sizeof(vis));
dfs(zx,zy);//不推石头直接能吃的金币个数
ans=res;
ans1=0;
solove(0,0);
printf("%d\n",ans+ans1);
}
}
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

int a[1005],b[1005],dp[1005],n,m;

int LICS()
{
int i,j,MAX;
memset(dp,0,sizeof(dp));
for(i = 1; i<=n; i++)
{
MAX = 0;
for(j = 1; j<=m; j++)
{
if(a[i]>b[j] && MAX<dp[j])
MAX = dp[j];
if(a[i]==b[j])
dp[j] = MAX+1;
}
}
MAX = 0;
for(i = 1; i<=m; i++)
if(MAX<dp[i])
MAX = dp[i];
return MAX;
}

int main()
{
int T,i;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i = 1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
for(i = 1;i<=m;i++)
scanf("%d",&b[i]);
printf("%d\n",LICS());
}

return 0;
}

​​1128: Download Station​​

#include <stdio.h>
#include <string.h>
#define CLR(a) (memset(a,0,sizeof(a)))
#define N 100
char g[N][N],vis[N];
int n;
int ord[N],id[N],cnt,din[N],dout[N];
void dfs(int u)
{
int v;
vis[u]=1;
for(v=0;v<n;v++)
{
if(g[u][v]&&!vis[v]) dfs(v);
}
ord[cnt++]=u;
}
void rdfs(int u)
{
int v;
vis[u]=1,id[u]=cnt;
for(v=0;v<n;v++)
{
if(g[v][u]&&!vis[v]) rdfs(v);
}
}
void kosaraju()
{
int i,j,t,a,b;
CLR(vis);
for(i=0,cnt=0;i<n;i++)
{
if(!vis[i]) dfs(i);
}
CLR(vis);
for(t=n-1,cnt=0;t>=0;t--)
{
i=ord[t];
if(!vis[i])
{
rdfs(i),cnt++;
}
}
CLR(din),CLR(dout);
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if((id[i]^id[j]) && (g[i][j] || g[j][i]))
{
dout[id[i]]+=g[i][j],din[id[j]]+=g[i][j];
dout[id[j]]+=g[j][i],din[id[i]]+=g[j][i];
}
}
}
for(i=0,a=0,b=0;i<cnt;i++) a+=dout[i]==0?1:0,b+=din[i]==0?1:0;
if(cnt==1) printf("0\n");
else printf("%d\n",a>b?a:b);
}
int main()
{
int i,j;
while(~scanf("%d",&n))
{
CLR(g);
for(i=0;i<n;i++)
{
while(scanf("%d",&j)&&j) g[i][j-1]=1;
}
kosaraju();
}
return 0;
}

​​1129: 送货到家​​

#include<algorithm>
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
long long d[1<<15][16];
long long w[16][16],n;
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(d,0x3f3f3f3f,sizeof d);
long long ans=1e9+7;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
scanf("%lld",&w[i][j]);
if(w[i][j]==0)w[i][j]=1e9+7;
}
}
d[1][0]=0;
for(int i=1;i<(1<<n)-1;i++)
{
for(int j=0;j<n;j++)
{
if(d[i][j]==0x3f3f3f3f)continue;
if((i&(1<<j))==0)continue;
for(int k=0;k<n;k++)
{
if((i&(1<<k)))continue;
d[i|(1<<k)][k]=min(d[i|(1<<k)][k],d[i][j]+w[k][j]);
}
}
}
for(int i=0;i<n;i++)
{
ans=min(ans,d[(1<<n)-1][i]+w[i][0]);
}
if(ans>=1e9+7)puts("NoAnswer");
else printf("%lld\n",ans);
}
return 0;
}

​​1140: 序号互换​​

# include <stdio.h>
# include <ctype.h>
# include <memory.h>

char a[15];
char s[15];

int main()
{
int T, i, n;

scanf("%d", &T);
while (T--)
{
scanf("%s", a);
if (isdigit(a[0]))
{
i = 0;
n = atoi(a);
while (n > 0)
{
s[i] = (n+25) % 26 + 'A';
++i;
if (n % 26) n /= 26;
else {n /= 26; --n;}
}
while (i > 0) putchar(s[--i]);
putchar('\n');
memset(s, 0, sizeof(s));
}
else
{
i = n = 0;
while (a[i] != '\0')
{
n = 26*n + a[i]-'A'+1;
++i;
}
printf("%d\n", n);
}

}

return 0;
}

​​1156: Switching bulbs​​

#include <cstdio>
#include <algorithm>
using namespace std;

const int N = 100005;
int col[N] , v[N] , a[N];

bool cmp(int a , int b)
{
return a>b;
}

int main()
{
// freopen("a.in" , "r" , stdin);
int n , m;
while(scanf("%d%d" , &n , &m) == 2)
{
for(int i = 0 ; i<n ; i++)
scanf("%d" , col+i);
for(int i = 0 ; i<n ; i++)
scanf("%d" , v+i);

int val = 0;
for(int i=0 ; i<n ; i++)
if(col[i]){
val += v[i];
a[i] = -v[i];
}
else{
a[i] = v[i];
}
sort(a , a+n , cmp);
for(int i = 0 ; i<n ; i++){
if(a[i] < 0){
if(i == 0){
n = 1;
break;
}
if(-a[i] > a[i-1]) n = i;
else n = i+1;
break;
}
}
if(m<=n){
for(int i = 0 ; i<m ; i++)
val += a[i];
}
else{
for(int i = 0 ; i<n ; i++){
val += a[i];
}
if((m-n)&1) val -= a[n-1];
}
printf("%d\n" , val);
}
return 0;
}

​​1164: Dominating​​

#include <algorithm>
#include<cmath>
#include<map>
#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;
map<string, int> cnt;
char s[10][20];
struct zhuan
{
int k; //记录杀人次数
int bk; //记录被杀次数
};
int c[10] = {200, 275, 325, 400, 475, 575, 675, 800, 900, 1000};
int main()
{
while((scanf("%s", s[0]))!=EOF)
{
zhuan b[10];
int z[10]; //每个人的金钱数
for(int i=0; i<10; i++) //初始化
{
b[i].bk = 0;
b[i].k = 0;
z[i] = 4726;
}
cnt[s[0]] = 0;
for(int i=1; i<10; i++)
{
scanf("%s", s[i]);
cnt[s[i]] = i;
}
int n;
scanf("%d", &n);
char a[20], e[20];
for(int i=0; i<n; i++)
{
scanf("%s%s", a, e);
if(strcmp(a, e)!=0) //非自杀
{
if((cnt[a]<5&&cnt[e]<5)||(cnt[a]>=5&&cnt[e]>=5)) //杀的是队友
{
if(z[cnt[e]]-c[b[cnt[e]].bk]>0) //被杀的金钱还够减
{
z[cnt[e]] -= c[b[cnt[e]].bk];
}
else
z[cnt[e]] = 0;
b[cnt[e]].k = 0;
b[cnt[e]].bk++;
}
else //杀的不是队友
{
if(z[cnt[e]]-c[b[cnt[e]].bk]>0)
{
if(b[cnt[a]].k>=9) //杀的人>=10
z[cnt[a]] += c[9];
else
z[cnt[a]] += c[b[cnt[a]].k];
b[cnt[a]].k++;
z[cnt[e]] -= c[b[cnt[e]].bk];
b[cnt[e]].k = 0;
b[cnt[e]].bk++;
}
else
{
if(b[cnt[a]].k>=9)
z[cnt[a]] += c[9];
else
z[cnt[a]] += c[b[cnt[a]].k];
z[cnt[e]] = 0;
b[cnt[a]].k++;
b[cnt[e]].bk++;
b[cnt[e]].k = 0;
}
}
}
}
for(int i=0; i<10; i++)
{
printf("%d\n", z[i]);
}
}
return 0;
}

​​1174: Shining Gems​​

# include <stdio.h>

const int d[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};

int n, m, f0, f1;
char f[1005][1005];

int check(int i, int j);
void n_swap(char *x, char *y);

int main()
{
int i, j, k, ni, nj;

while (~scanf("%d%d", &n, &m))
{
for (i = 1; i <= n; ++i)
scanf("%s", f[i]+1);

f0 = f1 = 0;
for (i = 1; !f0 && i <= n; ++i)
for (j = 1; j <= m; ++j)
{
if (check(i,j))
{
f0 = 1;
break;
}
for (k = 0; !f1 && k < 4; ++k)
{
ni = i + d[k][0];
nj = j + d[k][1];
if (ni<=n && ni>=1 && nj>=1 && nj <= m)
{
n_swap(&f[ni][nj], &f[i][j]);
if (check(ni, nj)) f1 = 1;
n_swap(&f[ni][nj], &f[i][j]);
}
}
}

if (f0) puts("Combo");
else if (f1) puts("Enjoy It");
else puts("Game Over");
}

return 0;
}

int check(int i, int j)
{
int k, cnt = 0;
char ch = f[i][j];

if ((k=i-2) <= 0) k = 1;
while (k <= n && ch != f[k][j]) ++k;
while (cnt < 3 && k <= n && ch == f[k++][j]) ++cnt;
if (cnt >= 3) return 1;
cnt = 0;
if ((k = j-2) <= 0) k = 1;
while (k <= m && ch != f[i][k]) ++k;
while (cnt < 3 && k <= m && ch == f[i][k++]) ++cnt;
if (cnt >= 3) return 1;
return 0;
}

void n_swap(char *x, char *y)
{
char ch;

ch = *x;
*x = *y;
*y = ch;
}

​​1175: A Tour Around Hangzhou​​

#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
#define INF 0x3f3f3f
#define MAX_N 10005
#define MAX_C 15
using namespace std;

typedef pair<int,int> P;
struct edge{int to,cost;};
vector<edge> G[MAX_N];
int d[MAX_N];

int V,E;

int dijkstra(int s,int t){
priority_queue<P,vector<P>,greater<P> > que;
que.push(P(0,s));
fill(d,d+V,INF);
d[s]=0;
while(!que.empty()){
P p=que.top();que.pop();
int c=p.first,v=p.second;
if(c>d[v]) continue;
for(int i=0;i<G[v].size();i++){
edge &e=G[v][i];
int dist=c+e.cost;
if(d[e.to]>dist){
d[e.to]=dist;
que.push(P(dist,e.to));
}
}
}
return d[t];
}

int mp[MAX_C][MAX_C];
int dp[1<<MAX_C][MAX_C];
int res[MAX_C],N,se;

void slove(){
for(int S=0;S<1<<N;S++) fill(dp[S],dp[S]+N,INF);
dp[(1<<N)-1][0]=0;
for(int S=(1<<N)-2;S>=0;S--)
for(int v=0;v<N;v++)
for(int u=0;u<N;u++)
if(!(S>>u&1))
dp[S][v]=min(dp[S][v],dp[S|1<<u][u]+mp[v][u]);
if(dp[0][0]==INF) puts("What a pity");
else printf("%d\n",dp[0][0]);
}

int main()
{
int x,y,c;
while(scanf("%d%d%d",&V,&E,&N)!=EOF){
for(int i=0;i<E;i++){
scanf("%d%d%d",&x,&y,&c);
G[x].push_back(edge{y,c});
G[y].push_back(edge{x,c});
}

for(int i=0;i<N;i++)
scanf("%d",&res[i]);
scanf("%d",&se);
bool flag=false;
for(int i=0;i<N;i++)
if(res[i]==se){
swap(res[0],res[i]);
flag=true;
break;
}
if(!flag){
swap(res[0],res[N]);
res[0]=se;
N++;
}

for(int i=0;i<N;i++){
for(int j=i+1;j<N;j++){
mp[i][j]=mp[j][i]=dijkstra(res[i],res[j]);
}
mp[i][i]=0;
}

slove();

for(int i=0;i<V;i++)
while(!G[i].empty())
G[i].pop_back();
}
return 0;
}

​​1179: Sum​​

#include<stdio.h>

double solve(double x)
{
double k,n,n2,m;
n=double(int(x));
n2=double(int(x/2));
m=n-n2;
double sum;
sum=(1+n2)*n2*1.0/2.0-(n2+1 +n)*m*1.0/2.0+m*x;
return sum;
}
int main()
{
double x;
while(scanf("%lf",&x)==1)
printf("%.2lf\n",solve(x));
return 0;
}

​​1182: 表达式​​

#include <stdio.h>
#include <string.h>
#define INI 0
#define NUM 1
#define OPT 2
#define WRN -1
#define N 1024
int table[4][130];
char s[N];
int n;
void init()
{
int state,ch;
memset(table,0xff,sizeof(table));
for(ch='0';ch<='9';ch++) table[INI][ch]=table[NUM][ch]=table[OPT][ch]=NUM;
table[INI]['+']=OPT;
table[INI]['-']=OPT;

table[NUM]['+']=OPT;
table[NUM]['-']=OPT;
table[NUM]['*']=OPT;
table[NUM]['/']=OPT;
}
int dfa(int a,int b)
{
int i,j,state=INI;
if(a>b) return WRN;
for(i=a;i<=b;i++)
{
if(s[i]==' ' || s[i]=='\t') continue;
if(s[i]=='(')
{
if(state==NUM) return WRN;
int cnt=1;
for(j=i+1;j<=b;j++)
{
if(s[j]=='(') cnt++;
else if(s[j]==')') cnt--;
if(cnt==0) break;
}
if(cnt || dfa(i+1,j-1)!=NUM) return WRN;
state=NUM;
i=j;
}
else state=table[state][s[i]];
if(state==WRN) return WRN;
}
if(state==NUM) return NUM;
return WRN;
}
int main()
{
init();
while(gets(s))
{
n=strlen(s);
if(n==0) puts("");
else printf("%s\n",dfa(0,n-1)==NUM?"Yes":"No");
}
return 0;
}

​​1183: 计算表达式的值​​

#include <stdio.h>
#define MAX (100 + 10)
char szData[MAX];

void TrimSpace(char* pszData)
{
char* pszRead = pszData;
char* pszWrite = pszData;
while (*pszRead)
{
//由于数据中有\t,与先前题目描述不符合,不处理掉就直接超时了
if (*pszRead != ' ' && *pszRead != '\t')
{
*pszWrite++ = *pszRead;
}
++pszRead;
}
*pszWrite = '\0';
}

//nKind代表前一个运算符合的优先级,开始时是0,+-是1,*/是2
double Cal(char*& pszData, int nKind)
{
double fAns = 0.0;
while (*pszData && *pszData != ')')//表达式终止的条件是到达'\0'或者碰到右括号
{
if (*pszData >= '0' && *pszData <= '9')
{
fAns = 10 * fAns + *pszData - '0';
++pszData;
}
else if (*pszData == '+')
{
if (nKind >= 1)
{
return fAns;
}
++pszData;
fAns += Cal(pszData, 1);
}
else if (*pszData == '-')
{
if (nKind >= 1)
{
return fAns;
}
++pszData;
fAns -= Cal(pszData, 1);
}
else if (*pszData == '*')
{
if (nKind >= 2)
{
return fAns;
}
++pszData;
fAns *= Cal(pszData, 2);
}
else if (*pszData == '/')
{
if (nKind >= 2)
{
return fAns;
}
++pszData;
fAns /= Cal(pszData, 2);
}
else if (*pszData == '(')
{
++pszData;
fAns = Cal(pszData, 0);
++pszData;//移到')'后面
return fAns;//一个括号内的是一个完整的表达式,因此直接返回
}
}

return fAns;
}

int main()
{
while (gets(szData))
{
TrimSpace(szData);
char* pszData = szData;
printf("%.4f\n", Cal(pszData, 0));
}
}

​​1184: 格林布的地雷​​

#include <stdio.h>
#include <string.h>
#define MAX(a,b) ((a)>(b)?(a):(b))
#define N 501
int n,m,g[N][N],d[N],path[N],top;
void dfs(int u)
{
int v;
for(v=1;v<=n;v++)
{
if(g[u][v])
{
g[u][v]--;
g[v][u]--;
dfs(v);
}
}
path[top++]=u;
}
int main()
{
int i,a,b,start;
while(~scanf("%d",&m))
{
memset(g,0,sizeof(g));
memset(d,0,sizeof(d));
n=0;
for(i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
g[a][b]++;
g[b][a]++;
d[a]++;
d[b]++;
n=MAX(n,MAX(a,b));
}
for(start=1;d[start]==0 && start<=n;start++);
for(i=start;(d[i]&1)==0 && i<=n;i++);
if(i<=n) start=i;
top=0;
dfs(start);
for(i=top-1;i>=0;i--) printf("%d\n",path[i]);
}
return 0;
}

​​1186: BMW图形文字识别​​

#include<stdio.h>
#include<iostream>
#include<queue>
#include<string.h>
using namespace std;

int hash1[209][209];
int map[209][209];
int ne[209][209];
int diri[4]={0,-1,0,1};
int dirj[4]={-1,0,1,0};

int used[10099];

struct data
{
int ni,nj;
};

int n,m;

void bfs(int x,int y,int add)
{
queue<data>qq;
int i,j;
data f,s,t;
f.ni=x;
f.nj=y;
qq.push(f);
while(!qq.empty())
{
s=qq.front();
qq.pop();
for(i=0;i<=3;i++)
{
t.ni=s.ni+diri[i];
t.nj=s.nj+dirj[i];

if(t.ni>=1&&t.ni<=n&&t.nj>=1&&t.nj<=m&&(hash1[t.ni][t.nj]==0)&&map[t.ni][t.nj]==1)
{
hash1[t.ni][t.nj]=add;
qq.push(t);
}
}
}
}

int main()
{
char temp;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(hash1,0,sizeof(hash1));
memset(used,0,sizeof(used));

int i,j;
char ss[1009];
for(i=1;i<=n;i++)
{
//getchar();
scanf("%s",ss);
for(j=1;j<=m;j++)
{
temp=ss[j-1];
if(temp=='_')
map[i][j]=0;
else
map[i][j]=1;
}
}


int add=1;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(hash1[i][j]==0&&map[i][j]==1)
{
bfs(i,j,add);
add++;
}
}
}
/*
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
printf("%d",hash1[i][j]);
}
printf("\n");
}*/

add=1;
int k;
int B=0,M=0,W=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(hash1[i][j]==0)continue;
if(used[hash1[i][j]]==1)continue;

add==hash1[i][j];

int temp=1;
for(k=j+1;k<=m;k++)
{
if(hash1[i][k]!=0&&hash1[i][k]!=add)
{
break;
}

if(hash1[i][k]!=0&&used[hash1[i][k]]==0)
{
if(hash1[i][k-1]==0)
temp++;
}

}
j=k;

used[add]=1;
if(temp==1)
{
// printf("%d %d\n",i,j);
B++;
}
if(temp==2)
M++;
if(temp==3)
W++;
add++;
}
}

printf("%d %d %d\n",B,M,W);

}
return 0;
}

​​1196: Staginner 去爬山​​

#include<stdio.h>
#include<string.h>
#define N 105

int dx[] = { 0, 0, 1, -1};
int dy[] = { 1, -1, 0, 0};
int map[N][N], vis[N][N];
int n, m;
int h, maxh;
void dfs( int x, int y)
{
int newx, newy;
for( int i = 0; i < 4; i ++)
{
newx = x + dx[i];
newy = y + dy[i];
if( map[newx][newy] && !vis[newx][newy])
{
vis[newx][newy] = 1;
h = n - newx + 1;
if( maxh < h) maxh = h;
dfs( newx, newy);
}
}
}

int main()
{
while( scanf( "%d%d", &n, &m) != EOF)
{
maxh = 0;
memset( map, 0, sizeof( map) ); //这句必不可少
for( int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j ++)
scanf( "%d", &map[i][j]);
memset( vis, 0, sizeof( vis) );
int i = n;
for( int j = 1; j <= m; j ++)
{
if( !vis[i][j] && map[i][j] )
{
vis[i][j] = 1;
dfs( i, j);
}
}
printf( "%d\n", maxh);
}
return 0;
}