题意:给一个表格,格子中的某些位置是其他格子的累加和,输出算好的格子
思路:既然有先后关系,那就用拓扑排序,把二维的转化为一维的
PS:列数认为是1000就能过,照题目的18278要MLE
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<stdlib.h>
#include<math.h>
#include<vector>
#include<list>
#include<map>
#include<stack>
#include<queue>
#include<algorithm>
#include<numeric>
#include<functional>
using namespace std;
typedef long long ll;
const int maxn = 1005; //18278
string s;
int d[1000*maxn],n,m;
vector<int> g[maxn*1000];
queue<int> q;
map<int,int> counts;
void init(int x)
{
counts.clear();
for(int i=0;i<=x;i++)
g[i].clear();
while(!q.empty())
q.pop();
}
void add(int u,int v)
{
g[u].push_back(v);
counts[v]++;
}
bool topsort()
{
int sum=n*m; //n 节点总数
bool flag=false;
for(int i=0;i<n*m;i++) //入度为0入栈
{
if(counts.find(i) == counts.end())
q.push(i);
}
while(!q.empty())
{
//if(q.size() > 1) 不能确定排名唯一性
sum--;
int j=q.front();
q.pop();
for(int k=0;k<g[j].size();k++)
{
d[g[j][k]] += d[j];
if(--counts[g[j][k]]==0)
q.push(g[j][k]);
}
}
if(sum>0)
return false; //表明存在回路
return true; //OK
}
void solve(int x,int y,string &s)
{
if(s[0] != '=')
{
int sum = 0;
for(int i = 0; s[i] != '\0'; i++)
{
sum = sum *10 + s[i] - '0';
}
d[x*m+y] = sum;
//printf("%d,%d] %d\n",x+1,y+1,sum);
}
else
{
int cnt = 1,j,sum,num;
while(1)
{
sum = 0;
while(1)
{
sum = sum * 26+ (s[cnt] - 'A' + 1);
cnt++;
if('0' <= s[cnt] && s[cnt] <= '9')
break;
}
num = 0;
while(1)
{
num = num *10 + s[cnt] - '0';
cnt++;
if(s[cnt] == '+' || s[cnt] == '\0')
{
sum--;num--;
add(num*m+sum,x*m+y);
//printf("%d,%d] -> %d,%d]\n",num+1,sum+1,x,y);
break;
}
}
if(s[cnt] == '\0')
break;
else
cnt++;
}
}
}
int main(void)
{
int T,i,j;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&m,&n);
init(m*n);
memset(d,0,sizeof d);
for(i = 0; i < n; i++)
{
for(j = 0; j < m; j++)
{
cin>>s;
solve(i,j,s);
}
}
topsort();
for(i = 0; i < n*m; i++)
{
printf("%d%c",d[i],i%m+1 == m?'\n':' ');
}
}
return 0;
}